seed data

This commit is contained in:
2025-12-30 18:33:15 +01:00
parent 83371ea839
commit 92226800df
306 changed files with 1753 additions and 501 deletions

268
plans/media-seeding-plan.md Normal file
View File

@@ -0,0 +1,268 @@
# Media Seeding Plan for Team Logos and Driver Avatars
## Executive Summary
This plan addresses the robust seeding of media assets (driver avatars and team logos) in the GridPilot development environment. The solution leverages existing static files for avatars and provides a reliable, Docker-compatible approach for team logos using Next.js API routes that serve SVG placeholders.
## Current State Analysis
### What Exists
1. **Static Avatar Files**: Three default avatars exist in `apps/website/public/images/avatars/`:
- `male-default-avatar.jpg`
- `female-default-avatar.jpeg`
- `neutral-default-avatar.jpeg`
2. **Next.js Image Configuration**: `apps/website/next.config.mjs` is configured with:
- Remote patterns for `localhost:3001` (API)
- Remote patterns for `api:3000` (Docker API)
- SVG support enabled
- Image optimization disabled in development
3. **Media Controller**: `apps/api/src/domain/media/MediaController.ts` already generates SVG placeholders for:
- Team logos (`/api/media/teams/:teamId/logo`)
- Driver avatars (`/api/media/drivers/:driverId/avatar`)
- League logos, covers, track images, etc.
4. **Current Seeding Logic**: `SeedRacingData.ts` calls `seedMediaAssets()` which sets URLs in the media repository.
### Problems Identified
1. **Driver Avatars**: Current seeding uses `/api/media/avatar/:driverId` which generates SVG placeholders, not static files
2. **Team Logos**: Current seeding uses `/api/media/teams/:teamId/logo` which generates SVG placeholders
3. **InMemoryMediaRepository**: Stores URLs but doesn't provide actual file serving
4. **No Static File Integration**: The existing static avatars aren't being used in seeding
## Solution Design
### 1. Driver Avatars Strategy (Static Files)
**Goal**: Use existing static avatar files for all seeded drivers.
**Implementation**:
#### A. Enhanced Driver Seeding Logic
```typescript
// In adapters/bootstrap/SeedRacingData.ts - seedMediaAssets() method
private async seedMediaAssets(seed: any): Promise<void> {
const baseUrl = this.getMediaBaseUrl();
// Seed driver avatars using static files
for (const driver of seed.drivers) {
const avatarUrl = this.getDriverAvatarUrl(driver.id);
const mediaRepo = this.seedDeps.mediaRepository as any;
if (mediaRepo.setDriverAvatar) {
mediaRepo.setDriverAvatar(driver.id, avatarUrl);
}
}
// ... rest of seeding
}
private getDriverAvatarUrl(driverId: string): string {
// Use deterministic selection based on driver ID
const numericSuffixMatch = driverId.match(/(\d+)$/);
let useFemale = false;
if (numericSuffixMatch) {
const numericSuffix = parseInt(numericSuffixMatch[1], 10);
useFemale = numericSuffix % 2 === 0;
} else {
// Fallback hash
let hash = 0;
for (let i = 0; i < driverId.length; i++) {
hash = (hash * 31 + driverId.charCodeAt(i)) | 0;
}
useFemale = Math.abs(hash) % 2 === 0;
}
// Return static file paths that Next.js can serve
if (useFemale) {
return '/images/avatars/female-default-avatar.jpeg';
} else {
return '/images/avatars/male-default-avatar.jpg';
}
}
```
#### B. Next.js Static File Serving
The existing Next.js configuration already supports serving static files from `public/images/avatars/`. These URLs will work directly from the website container.
### 2. Team Logos Strategy (SVG Generation)
**Goal**: Provide reliable, Docker-compatible team logos that work without external dependencies.
**Implementation**:
#### A. Enhanced Team Seeding Logic
```typescript
// In adapters/bootstrap/SeedRacingData.ts - seedMediaAssets() method
// Seed team logos
for (const team of seed.teams) {
const logoUrl = `${baseUrl}/api/media/teams/${team.id}/logo`;
const mediaRepo = this.seedDeps.mediaRepository as any;
if (mediaRepo.setTeamLogo) {
mediaRepo.setTeamLogo(team.id, logoUrl);
}
}
```
#### B. API Route Enhancement
The existing `MediaController.ts` already provides `/api/media/teams/:teamId/logo` which generates SVG placeholders. This is perfect for Docker development because:
- No external network dependencies
- Deterministic generation based on team ID
- Works in Docker containers
- Served via the API container (port 3001)
#### C. Next.js Rewrites Configuration
The existing `next.config.mjs` already has rewrites that route `/api/*` to the API container:
```javascript
async rewrites() {
const baseUrl = 'http://api:3000';
return [
{
source: '/api/:path*',
destination: `${baseUrl}/:path*`,
},
];
}
```
This means:
- Website requests `/api/media/teams/team-1/logo` → Next.js rewrites to `http://api:3000/api/media/teams/team-1/logo`
- API serves SVG placeholder
- Next.js Image component can optimize/cache it
### 3. Architecture Flow
```
Seeding Phase:
1. SeedRacingData.execute() creates drivers/teams
2. seedMediaAssets() calculates URLs
3. InMemoryMediaRepository stores: driverId → avatarUrl, teamId → logoUrl
4. URLs are stored in database entities
Runtime Phase (Website):
1. Component requests driver avatar: `/images/avatars/male-default-avatar.jpg`
2. Next.js serves static file directly from public directory
Runtime Phase (Team Logo):
1. Component requests team logo: `/api/media/teams/team-1/logo`
2. Next.js rewrite: → `http://api:3000/api/media/teams/team-1/logo`
3. API generates SVG and returns
4. Next.js Image component optimizes/caches
```
## Implementation Steps
### Step 1: Update SeedRacingData.ts
Modify the `seedMediaAssets()` method to use static files for drivers and existing API routes for teams.
### Step 2: Update InMemoryMediaRepository
Ensure it has methods for storing/retrieving media URLs:
```typescript
setDriverAvatar(driverId: string, url: string): void;
setTeamLogo(teamId: string, url: string): void;
getDriverAvatar(driverId: string): Promise<string | null>;
getTeamLogo(teamId: string): Promise<string | null>;
```
### Step 3: Verify Next.js Configuration
Ensure `next.config.mjs` has:
- Proper remote patterns for localhost and Docker API
- SVG support enabled
- Image optimization disabled in dev
### Step 4: Test the Flow
1. Start Docker development environment
2. Trigger database seeding
3. Verify driver avatars point to static files
4. Verify team logos point to API routes
5. Test that URLs resolve correctly in website
## Benefits of This Approach
### Reliability
- **No external dependencies**: No network calls to external services
- **Docker-compatible**: Works entirely within Docker network
- **Deterministic**: Same IDs always produce same URLs
### Performance
- **Fast**: Static files served directly, SVG generated on-demand
- **Cached**: Next.js can cache API responses
- **No cold starts**: No external service initialization needed
### Maintainability
- **Clean architecture**: Follows existing patterns
- **Testable**: Easy to verify URLs are correct
- **Extensible**: Can add more media types easily
### Developer Experience
- **Simple**: No API keys or external services to configure
- **Fast**: No waiting for external API responses
- **Offline-capable**: Works without internet connection
## Risk Mitigation
### Risk: Static files not accessible in Docker
**Mitigation**: Files are in `apps/website/public/images/avatars/` which is mounted via volumes in docker-compose.dev.yml
### Risk: API routes not working in Docker
**Mitigation**: Next.js rewrites already route `/api/*` to `http://api:3000` which is the Docker API service
### Risk: Image optimization fails
**Mitigation**: Set `unoptimized: true` in development, which is already configured
### Risk: URLs don't match between seeding and runtime
**Mitigation**: Use consistent URL generation logic in both seeding and display components
## Testing Strategy
### Unit Tests
- Verify `getDriverAvatarUrl()` returns correct static file paths
- Verify `seedMediaAssets()` calls repository methods correctly
### Integration Tests
- Verify seeding creates correct URLs in database
- Verify API routes return SVG for team logos
- Verify static files are accessible via Next.js
### E2E Tests
- Load dashboard page
- Verify driver avatars display correctly
- Verify team logos display correctly
- Verify no console errors for missing images
## Files to Modify
1. **`adapters/bootstrap/SeedRacingData.ts`**
- Update `seedMediaAssets()` method
- Add `getDriverAvatarUrl()` helper
2. **`adapters/racing/persistence/media/InMemoryMediaRepository.ts`**
- Ensure methods exist for avatar/logo storage
3. **`apps/website/next.config.mjs`**
- Verify configuration is correct for Docker
4. **`docker-compose.dev.yml`**
- Ensure volumes mount public directory
## Success Criteria
✅ Every driver has an avatar URL pointing to static files
✅ Every team has a logo URL pointing to API routes
✅ URLs work in Docker development environment
✅ No external network dependencies required
✅ Images display correctly in website UI
✅ Seeding is deterministic and reproducible
## Conclusion
This plan provides a robust, Docker-compatible solution for media seeding that leverages existing infrastructure:
- **Driver avatars**: Static files for reliability and speed
- **Team logos**: SVG generation for consistency and no external dependencies
- **Architecture**: Follows clean architecture principles
- **Docker support**: Works seamlessly in containerized development
The solution is simple, maintainable, and addresses all the constraints mentioned in the task.