seed data
This commit is contained in:
115
plans/seeds-plan.md
Normal file
115
plans/seeds-plan.md
Normal file
@@ -0,0 +1,115 @@
|
||||
# Comprehensive Seeding Plan for GridPilot
|
||||
|
||||
## Current Seeding Setup
|
||||
Current seeding in [`adapters/bootstrap`](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 in `bootstrap/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
|
||||
- [`User`](core/identity/domain/entities/User.ts)
|
||||
- [`Achievement`](core/identity/domain/entities/Achievement.ts)
|
||||
- [`UserAchievement`](core/identity/domain/entities/UserAchievement.ts)
|
||||
- [`SponsorAccount`](core/identity/domain/entities/SponsorAccount.ts)
|
||||
- [`ExternalGameRatingProfile`](core/identity/domain/entities/ExternalGameRatingProfile.ts)
|
||||
- [`RatingEvent`](core/identity/domain/entities/RatingEvent.ts)
|
||||
- [`AdminVoteSession`](core/identity/domain/entities/AdminVoteSession.ts)
|
||||
|
||||
### Racing Domain (primary, most seeded)
|
||||
- [`Driver`](core/racing/domain/entities/Driver.ts): id, iracingId, name, country, bio?, joinedAt
|
||||
- [`League`](core/racing/domain/entities/League.ts): 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`](core/racing/domain/entities/season/Season.ts): id, leagueId, gameId, name, year?, order?, status enum ['planned','active','completed','archived','cancelled'], start/endDate?, schedule?, schedulePublished bool, scoringConfig?, dropPolicy?, stewardingConfig?, maxDrivers?, participantCount
|
||||
- [`Team`](core/racing/domain/entities/Team.ts): id, name, tag, description, ownerId (DriverId), leagues[], createdAt
|
||||
- [`Standing`](core/racing/domain/entities/Standing.ts): id (leagueId:driverId), leagueId, driverId, points, wins, position, racesCompleted
|
||||
- Race-related: [`Race`](core/racing/domain/entities/Race.ts), [`RaceEvent`](core/racing/domain/entities/RaceEvent.ts), [`Session`](core/racing/domain/entities/Session.ts), [`Result`](core/racing/domain/entities/result/Result.ts), [`RaceRegistration`](core/racing/domain/entities/RaceRegistration.ts)
|
||||
- Stewarding: [`Protest`](core/racing/domain/entities/Protest.ts) (statuses), [`Penalty`](core/racing/domain/entities/penalty/Penalty.ts) (types enum, status)
|
||||
- Other: [`JoinRequest`](core/racing/domain/entities/JoinRequest.ts), [`LeagueMembership`](core/racing/domain/entities/LeagueMembership.ts), [`Sponsor`](core/racing/domain/entities/sponsor/Sponsor.ts), [`SeasonSponsorship`](core/racing/domain/entities/season/SeasonSponsorship.ts), [`LeagueWallet`](core/racing/domain/entities/league-wallet/LeagueWallet.ts), [`Transaction`](core/racing/domain/entities/league-wallet/Transaction.ts), 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*Factory` pattern.
|
||||
- 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 req3
|
||||
- `league-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)
|
||||
1. Extend factories for new states/combos.
|
||||
2. Add factories for non-racing entities.
|
||||
3. Update SeedRacingData to call all.
|
||||
4. EnsureInitialData for non-racing.
|
||||
|
||||
This plan covers **every single possible valid state** via systematic enum cartesian + edges (0/max/empty/full/pending/complete)."
|
||||
Reference in New Issue
Block a user