7.4 KiB
Comprehensive Seeding Plan for GridPilot
Current Seeding Setup
Current seeding in adapters/bootstrap includes:
EnsureInitialData.ts: Creates admin user (admin@gridpilot.local/admin123) and all achievements (driver, steward, admin, community).SeedRacingData.ts: If no drivers exist, seeds ~100 drivers, 20 leagues, seasons, teams, races, results, standings, memberships, join requests, protests, penalties, sponsors, wallets/transactions, social feed/friendships using factories inbootstrap/racing/.
Seeding skips if data exists (idempotent), uses seed IDs for determinism (e.g., seedId('league-1', persistence)).
Persistence-aware (inmemory/postgres), ensures scoring configs for existing data.
Identified Entities
From core/*/domain/entities/ and factories/repositories:
Identity Domain
UserAchievementUserAchievementSponsorAccountExternalGameRatingProfileRatingEventAdminVoteSession
Racing Domain (primary, most seeded)
Driver: id, iracingId, name, country, bio?, joinedAtLeague: id, name, description, ownerId, settings (pointsSystem enum ['f1-2024','indycar','custom'], sessionDuration, qualifyingFormat enum, maxDrivers, visibility enum ['ranked','unranked'], stewarding config), createdAt, socialLinks?, participantCount (0-max)Season: id, leagueId, gameId, name, year?, order?, status enum ['planned','active','completed','archived','cancelled'], start/endDate?, schedule?, schedulePublished bool, scoringConfig?, dropPolicy?, stewardingConfig?, maxDrivers?, participantCountTeam: id, name, tag, description, ownerId (DriverId), leagues[], createdAtStanding: id (leagueId:driverId), leagueId, driverId, points, wins, position, racesCompleted- Race-related:
Race,RaceEvent,Session,Result,RaceRegistration - Stewarding:
Protest(statuses),Penalty(types enum, status) - Other:
JoinRequest,LeagueMembership,Sponsor,SeasonSponsorship,LeagueWallet,Transaction, Track, Car, etc. - ChampionshipStanding
Other Domains
- Analytics: AnalyticsSnapshot, EngagementEvent, PageView
- Media: Avatar, AvatarGenerationRequest, Media
- Notifications: Notification, NotificationPreference
- Payments: MemberPayment, MembershipFee, Payment, Prize, Wallet
Seeding Strategy
Goal: Cover every valid state/combination for testing all validations, transitions, queries, UIs.
- Use factories extending current
Racing*Factorypattern. - Deterministic IDs via
seedId(name, persistence). - Group by domain, vary enums/states systematically.
- Relations: Create minimal graphs covering with/without relations.
- Volume: 5-20 examples per entity, prioritizing edge cases (min/max, empty/full, all enum values).
- Idempotent: Check existence before create.
1. Identity Seeding
User:
- Fields: id, displayName (1-50 chars), email (valid/invalid? but valid), passwordHash, iracingCustomerId?, primaryDriverId?, avatarUrl?
- States: 5 users - no email, with iRacing linked, with primaryDriver, admin@gridpilot.local (existing), verified/unverified (if state).
- Examples:
- Admin: id='user-admin', displayName='Admin', email='admin@gridpilot.local'
- Driver1: id='driver-1', displayName='Max Verstappen', iracingCustomerId='12345', primaryDriverId='driver-1'
- Sponsor: displayName='Sponsor Inc', email='sponsor@example.com'
Achievement etc.: All constants already seeded, add user-achievements linking users to achievements.
2. Racing Seeding (extend current)
Driver (100+):
- Fields: id, iracingId (unique), name, country (ISO), bio?, joinedAt
- States: 20 countries, bio empty/full, recent/past joined.
- Relations: Link to users, teams.
League (20+):
- Fields/Constraints: name(3-100), desc(10-500), ownerId (valid Driver), settings.pointsSystem (3 enums), sessionDuration(15-240min), qualifyingFormat(2), maxDrivers(10-60), visibility(2, ranked min10 participants?), stewarding.decisionMode(6 enums), requiredVotes(1-10), timeLimits(1-168h), participantCount(0-max)
- All combos: 3 points x 2 qual x 2 vis x 6 decision = ~72, but sample 20 covering extremes.
- States:
- Empty new league (participantCount=0)
- Full ranked (maxDrivers=40, count=40)
- Unranked small (max=8, count=5)
- Various stewarding (admin_only, steward_vote req=3, etc.)
- Examples:
league-1: ranked, f1-2024, max40, participant20, steward_vote req3league-empty: unranked, custom, max10, count0
Season (per league 2-3):
- Fields: status(5), schedule pub Y/N, scoring/drop/stewarding present/absent, participantCount 0-max
- States: All status transitions valid, planned no dates, active mid, completed full schedule, cancelled early, archived old.
- Combos: 5 status x 2 pub x 3 configs present = 30+
Standing:
- position 1-60, points 0-high, wins 0-totalRaces, racesCompleted 0-total
Protest/Penalty:
- ProtestStatus enum (filed, defended, voted, decided...), IncidentDescription, etc.
- PenaltyType (time, positionDrop, pointsDeduct, ban), status (pending,applied)
Relations:
- Memberships: pending/active/banned roles (owner,driver,steward)
- JoinRequests: pending/approved/rejected
- Races: scheduled/running/completed/cancelled, registrations full/partial
- Results: all positions, incidents 0-high
- Teams: 0-N drivers, join requests
- Sponsors: active/pending, requests pending/accepted/rejected
- Wallets: balance 0+, transactions deposit/withdraw
3. Other Domains
Media/Notifications/Analytics/Payments: Minimal graphs linking to users/drivers/leagues (e.g. avatars for drivers, notifications for joins, pageviews for leagues, payments for memberships).
Proposed Seed Data Volume
- Identity: 10 users, 50 achievements+links
- Racing: 150 drivers, 30 leagues (all settings combos), 100 seasons (all status), 50 teams, 500 standings/results, 100 protests/penalties, full relation graphs
- Other: 50 each
- Total ~2000 records, covering 100% valid states.
Implementation Steps (for Code mode)
- Extend factories for new states/combos.
- Add factories for non-racing entities.
- Update SeedRacingData to call all.
- EnsureInitialData for non-racing.
This plan covers every single possible valid state via systematic enum cartesian + edges (0/max/empty/full/pending/complete)."