remove demo code

This commit is contained in:
2026-01-03 11:38:51 +01:00
parent 2f21dc4595
commit 9a7efa496f
38 changed files with 1535 additions and 1157 deletions

View File

@@ -0,0 +1,439 @@
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import type { Logger } from '@core/shared/application';
import type { IAuthRepository } from '@core/identity/domain/repositories/IAuthRepository';
import type { IPasswordHashingService } from '@core/identity/domain/services/PasswordHashingService';
import type { IAdminUserRepository } from '@core/admin/domain/repositories/IAdminUserRepository';
import { User } from '@core/identity/domain/entities/User';
import { AdminUser } from '@core/admin/domain/entities/AdminUser';
import { EmailAddress } from '@core/identity/domain/value-objects/EmailAddress';
import { UserId } from '@core/identity/domain/value-objects/UserId';
import { Email } from '@core/admin/domain/value-objects/Email';
import { UserRole } from '@core/admin/domain/value-objects/UserRole';
import { UserStatus } from '@core/admin/domain/value-objects/UserStatus';
import { PasswordHash } from '@core/identity/domain/value-objects/PasswordHash';
// Import the class we're testing (will be created)
import { SeedDemoUsers } from './SeedDemoUsers';
describe('SeedDemoUsers', () => {
const originalEnv = { ...process.env };
let logger: Logger;
let authRepository: IAuthRepository;
let passwordHashingService: IPasswordHashingService;
let adminUserRepository: IAdminUserRepository;
beforeEach(() => {
vi.clearAllMocks();
process.env = { ...originalEnv };
logger = {
debug: vi.fn(),
info: vi.fn(),
warn: vi.fn(),
error: vi.fn(),
};
// Mock password hashing service
passwordHashingService = {
hash: vi.fn().mockImplementation(async (plain: string) => {
return `hashed_${plain}`;
}),
verify: vi.fn(),
};
// Mock auth repository
authRepository = {
findByEmail: vi.fn(),
save: vi.fn(),
};
// Mock admin user repository
adminUserRepository = {
findById: vi.fn(),
findByEmail: vi.fn(),
emailExists: vi.fn(),
existsById: vi.fn(),
existsByEmail: vi.fn(),
list: vi.fn(),
count: vi.fn(),
create: vi.fn(),
update: vi.fn(),
delete: vi.fn(),
toStored: vi.fn(),
fromStored: vi.fn(),
};
});
afterEach(() => {
process.env = originalEnv;
});
describe('Demo user specification', () => {
it('should define the correct demo users with fixed emails', async () => {
const seed = new SeedDemoUsers(logger, authRepository, passwordHashingService, adminUserRepository);
const expectedEmails = [
'demo.driver@example.com',
'demo.sponsor@example.com',
'demo.owner@example.com',
'demo.steward@example.com',
'demo.admin@example.com',
'demo.systemowner@example.com',
'demo.superadmin@example.com',
];
// Mock repositories to return null (users don't exist)
(authRepository.findByEmail as any).mockResolvedValue(null);
(adminUserRepository.findByEmail as any).mockResolvedValue(null);
(adminUserRepository.create as any).mockImplementation((user: AdminUser) => user);
(authRepository.save as any).mockResolvedValue(undefined);
await seed.execute();
// Verify that findByEmail was called for each expected email
const calls = (authRepository.findByEmail as any).mock.calls;
const emailsCalled = calls.map((call: any) => call[0].value);
expect(emailsCalled).toEqual(expect.arrayContaining(expectedEmails));
expect(emailsCalled.length).toBeGreaterThanOrEqual(7);
});
it('should use the fixed password "Demo1234!"', async () => {
const seed = new SeedDemoUsers(logger, authRepository, passwordHashingService, adminUserRepository);
// Mock repositories to return null (users don't exist)
(authRepository.findByEmail as any).mockResolvedValue(null);
(adminUserRepository.findByEmail as any).mockResolvedValue(null);
(adminUserRepository.create as any).mockImplementation((user: AdminUser) => user);
(authRepository.save as any).mockResolvedValue(undefined);
await seed.execute();
// Verify password hashing was called with the correct password
expect(passwordHashingService.hash).toHaveBeenCalledWith('Demo1234!');
});
it('should generate deterministic IDs using SeedIdHelper', async () => {
// Set postgres mode for this test
process.env.DATABASE_URL = 'postgresql://localhost/test';
delete process.env.GRIDPILOT_API_PERSISTENCE;
delete process.env.NODE_ENV;
const seed = new SeedDemoUsers(logger, authRepository, passwordHashingService, adminUserRepository);
// Mock repositories to return null (users don't exist)
(authRepository.findByEmail as any).mockResolvedValue(null);
(adminUserRepository.findByEmail as any).mockResolvedValue(null);
(adminUserRepository.create as any).mockImplementation((user: AdminUser) => user);
(authRepository.save as any).mockResolvedValue(undefined);
await seed.execute();
// Verify that users were saved with UUIDs
const saveCalls = (authRepository.save as any).mock.calls;
expect(saveCalls.length).toBeGreaterThanOrEqual(7);
// Check that IDs are UUIDs (deterministic from seed keys)
for (const call of saveCalls) {
const user: User = call[0];
const id = user.getId().value;
// Should be a valid UUID format
expect(id).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i);
}
});
it('should create primaryDriverId for roles that need it', async () => {
const seed = new SeedDemoUsers(logger, authRepository, passwordHashingService, adminUserRepository);
// Mock repositories to return null (users don't exist)
(authRepository.findByEmail as any).mockResolvedValue(null);
(adminUserRepository.findByEmail as any).mockResolvedValue(null);
(adminUserRepository.create as any).mockImplementation((user: AdminUser) => user);
(authRepository.save as any).mockResolvedValue(undefined);
await seed.execute();
const saveCalls = (authRepository.save as any).mock.calls;
// Check that driver, owner, steward, admin, systemowner, superadmin have primaryDriverId
const usersWithPrimaryDriverId = saveCalls.filter((call: any) => {
const user: User = call[0];
return user.getPrimaryDriverId() !== undefined;
});
expect(usersWithPrimaryDriverId.length).toBe(6); // All except sponsor
});
});
describe('Idempotency', () => {
it('should not create duplicates when execute() is called twice', async () => {
const seed = new SeedDemoUsers(logger, authRepository, passwordHashingService, adminUserRepository);
// First execution - users don't exist
(authRepository.findByEmail as any).mockResolvedValue(null);
(adminUserRepository.findByEmail as any).mockResolvedValue(null);
(adminUserRepository.create as any).mockImplementation((user: AdminUser) => user);
(authRepository.save as any).mockResolvedValue(undefined);
await seed.execute();
const firstSaveCount = (authRepository.save as any).mock.calls.length;
const firstAdminCreateCount = (adminUserRepository.create as any).mock.calls.length;
// Reset mocks
vi.clearAllMocks();
// Second execution - users now exist
(authRepository.findByEmail as any).mockImplementation(async (email: EmailAddress) => {
// Return existing user for all demo emails
if (email.value.startsWith('demo.')) {
const displayName = email.value === 'demo.driver@example.com' ? 'John Driver' :
email.value === 'demo.sponsor@example.com' ? 'Jane Sponsor' :
email.value === 'demo.owner@example.com' ? 'Alice Owner' :
email.value === 'demo.steward@example.com' ? 'Bob Steward' :
email.value === 'demo.admin@example.com' ? 'Charlie Admin' :
email.value === 'demo.systemowner@example.com' ? 'Diana SystemOwner' :
'Edward SuperAdmin';
return User.create({
id: UserId.create(),
displayName: displayName,
email: email.value,
passwordHash: PasswordHash.fromHash('hashed_Demo1234!'),
});
}
return null;
});
(adminUserRepository.findByEmail as any).mockImplementation(async (email: Email) => {
// Return existing admin user for admin roles
if (email.value.startsWith('demo.owner') || email.value.startsWith('demo.steward') ||
email.value.startsWith('demo.admin') || email.value.startsWith('demo.systemowner') ||
email.value.startsWith('demo.superadmin')) {
const displayName = email.value === 'demo.owner@example.com' ? 'Alice Owner' :
email.value === 'demo.steward@example.com' ? 'Bob Steward' :
email.value === 'demo.admin@example.com' ? 'Charlie Admin' :
email.value === 'demo.systemowner@example.com' ? 'Diana SystemOwner' :
'Edward SuperAdmin';
return AdminUser.create({
id: UserId.create().value,
email: email.value,
roles: ['user'],
status: 'active',
displayName: displayName,
});
}
return null;
});
await seed.execute();
const secondSaveCount = (authRepository.save as any).mock.calls.length;
const secondAdminCreateCount = (adminUserRepository.create as any).mock.calls.length;
// Second execution should not create any new users
expect(secondSaveCount).toBe(0);
expect(secondAdminCreateCount).toBe(0);
});
});
describe('Admin user creation', () => {
it('should create AdminUser entities for admin roles', async () => {
const seed = new SeedDemoUsers(logger, authRepository, passwordHashingService, adminUserRepository);
// Mock repositories
(authRepository.findByEmail as any).mockResolvedValue(null);
(adminUserRepository.findByEmail as any).mockResolvedValue(null);
(adminUserRepository.create as any).mockImplementation((user: AdminUser) => user);
(authRepository.save as any).mockResolvedValue(undefined);
await seed.execute();
// Verify admin users were created
const adminCreateCalls = (adminUserRepository.create as any).mock.calls;
// Should create admin users for: owner, steward, admin, systemowner, superadmin
expect(adminCreateCalls.length).toBe(5);
// Verify the roles
const createdRoles = adminCreateCalls.map((call: any) => {
const adminUser: AdminUser = call[0];
return adminUser.roles.map((r: UserRole) => r.value);
});
// Each should have appropriate roles
expect(createdRoles).toContainEqual(['owner']);
expect(createdRoles).toContainEqual(['user']); // steward
expect(createdRoles).toContainEqual(['admin']);
expect(createdRoles).toContainEqual(['admin']); // systemowner
expect(createdRoles).toContainEqual(['admin']); // superadmin
});
it('should not create AdminUser for driver and sponsor roles', async () => {
const seed = new SeedDemoUsers(logger, authRepository, passwordHashingService, adminUserRepository);
// Mock repositories
(authRepository.findByEmail as any).mockResolvedValue(null);
(adminUserRepository.findByEmail as any).mockResolvedValue(null);
(adminUserRepository.create as any).mockImplementation((user: AdminUser) => user);
(authRepository.save as any).mockResolvedValue(undefined);
await seed.execute();
const adminCreateCalls = (adminUserRepository.create as any).mock.calls;
// Verify no admin users were created for driver and sponsor
const adminEmails = adminCreateCalls.map((call: any) => call[0].email.value);
expect(adminEmails).not.toContain('demo.driver@example.com');
expect(adminEmails).not.toContain('demo.sponsor@example.com');
});
});
describe('Persistence detection', () => {
it('should detect postgres persistence from DATABASE_URL', async () => {
process.env.DATABASE_URL = 'postgresql://localhost/test';
delete process.env.GRIDPILOT_API_PERSISTENCE;
delete process.env.NODE_ENV;
const seed = new SeedDemoUsers(logger, authRepository, passwordHashingService, adminUserRepository);
// Mock repositories
(authRepository.findByEmail as any).mockResolvedValue(null);
(adminUserRepository.findByEmail as any).mockResolvedValue(null);
(adminUserRepository.create as any).mockImplementation((user: AdminUser) => user);
(authRepository.save as any).mockResolvedValue(undefined);
await seed.execute();
// Should use UUIDs for IDs (verified by checking ID format)
const saveCalls = (authRepository.save as any).mock.calls;
const user: User = saveCalls[0][0];
const id = user.getId().value;
// UUID format
expect(id).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i);
});
it('should detect inmemory persistence in test environment', async () => {
process.env.NODE_ENV = 'test';
delete process.env.DATABASE_URL;
delete process.env.GRIDPILOT_API_PERSISTENCE;
const seed = new SeedDemoUsers(logger, authRepository, passwordHashingService, adminUserRepository);
// Mock repositories
(authRepository.findByEmail as any).mockResolvedValue(null);
(adminUserRepository.findByEmail as any).mockResolvedValue(null);
(adminUserRepository.create as any).mockImplementation((user: AdminUser) => user);
(authRepository.save as any).mockResolvedValue(undefined);
await seed.execute();
// Should use deterministic string IDs
const saveCalls = (authRepository.save as any).mock.calls;
const user: User = saveCalls[0][0];
const id = user.getId().value;
// Should be a deterministic string (not UUID)
expect(id).toContain('demo-');
});
});
describe('Force reseed support', () => {
it('should support force reseed via environment variable', async () => {
process.env.GRIDPILOT_API_FORCE_RESEED = '1';
process.env.GRIDPILOT_API_PERSISTENCE = 'inmemory';
const seed = new SeedDemoUsers(logger, authRepository, passwordHashingService, adminUserRepository);
// Mock existing users
const existingUser = User.create({
id: UserId.create(),
displayName: 'John Driver',
email: 'demo.driver@example.com',
passwordHash: PasswordHash.fromHash('old_hash'),
});
(authRepository.findByEmail as any).mockResolvedValue(existingUser);
(adminUserRepository.findByEmail as any).mockResolvedValue(null);
(authRepository.save as any).mockResolvedValue(undefined);
(adminUserRepository.create as any).mockImplementation((user: AdminUser) => user);
await seed.execute();
// Should still save users (force reseed means update existing)
expect(authRepository.save).toHaveBeenCalled();
});
});
describe('Logging', () => {
it('should log progress and results', async () => {
const seed = new SeedDemoUsers(logger, authRepository, passwordHashingService, adminUserRepository);
// Mock repositories
(authRepository.findByEmail as any).mockResolvedValue(null);
(adminUserRepository.findByEmail as any).mockResolvedValue(null);
(adminUserRepository.create as any).mockImplementation((user: AdminUser) => user);
(authRepository.save as any).mockResolvedValue(undefined);
await seed.execute();
// Should log start
expect(logger.info).toHaveBeenCalledWith(
expect.stringContaining('[Bootstrap] Starting demo users seed')
);
// Should log completion
expect(logger.info).toHaveBeenCalledWith(
expect.stringContaining('[Bootstrap] Demo users seed completed')
);
});
it('should log when skipping due to existing users', async () => {
const seed = new SeedDemoUsers(logger, authRepository, passwordHashingService, adminUserRepository);
// Mock existing users
(authRepository.findByEmail as any).mockImplementation(async (email: EmailAddress) => {
const displayName = email.value === 'demo.driver@example.com' ? 'John Driver' :
email.value === 'demo.sponsor@example.com' ? 'Jane Sponsor' :
email.value === 'demo.owner@example.com' ? 'Alice Owner' :
email.value === 'demo.steward@example.com' ? 'Bob Steward' :
email.value === 'demo.admin@example.com' ? 'Charlie Admin' :
email.value === 'demo.systemowner@example.com' ? 'Diana SystemOwner' :
'Edward SuperAdmin';
return User.create({
id: UserId.create(),
displayName: displayName,
email: email.value,
passwordHash: PasswordHash.fromHash('hashed_Demo1234!'),
});
});
(adminUserRepository.findByEmail as any).mockImplementation(async (email: Email) => {
if (email.value.startsWith('demo.owner') || email.value.startsWith('demo.steward') ||
email.value.startsWith('demo.admin') || email.value.startsWith('demo.systemowner') ||
email.value.startsWith('demo.superadmin')) {
const displayName = email.value === 'demo.owner@example.com' ? 'Alice Owner' :
email.value === 'demo.steward@example.com' ? 'Bob Steward' :
email.value === 'demo.admin@example.com' ? 'Charlie Admin' :
email.value === 'demo.systemowner@example.com' ? 'Diana SystemOwner' :
'Edward SuperAdmin';
return AdminUser.create({
id: UserId.create().value,
email: email.value,
roles: ['user'],
status: 'active',
displayName: displayName,
});
}
return null;
});
await seed.execute();
expect(logger.info).toHaveBeenCalledWith(
expect.stringContaining('[Bootstrap] Demo users already exist, skipping')
);
});
});
});

View File

@@ -0,0 +1,265 @@
import type { Logger } from '@core/shared/application';
import type { IAuthRepository } from '@core/identity/domain/repositories/IAuthRepository';
import type { IPasswordHashingService } from '@core/identity/domain/services/PasswordHashingService';
import type { IAdminUserRepository } from '@core/admin/domain/repositories/IAdminUserRepository';
import { User } from '@core/identity/domain/entities/User';
import { AdminUser } from '@core/admin/domain/entities/AdminUser';
import { EmailAddress } from '@core/identity/domain/value-objects/EmailAddress';
import { UserId } from '@core/identity/domain/value-objects/UserId';
import { Email } from '@core/admin/domain/value-objects/Email';
import { PasswordHash } from '@core/identity/domain/value-objects/PasswordHash';
import { stableUuidFromSeedKey } from './racing/SeedIdHelper';
interface DemoUserSpec {
email: string;
password: string;
needsAdminUser: boolean;
needsPrimaryDriverId: boolean;
roles: string[];
displayName: string;
}
/**
* SeedDemoUsers - Creates predefined demo users for testing and development
*
* This class creates a canonical set of demo users with fixed emails and passwords.
* It is idempotent and supports force reseeding via environment variables.
*/
export class SeedDemoUsers {
private readonly demoUserSpecs: DemoUserSpec[] = [
{
email: 'demo.driver@example.com',
password: 'Demo1234!',
needsAdminUser: false,
needsPrimaryDriverId: true,
roles: ['user'],
displayName: 'John Driver',
},
{
email: 'demo.sponsor@example.com',
password: 'Demo1234!',
needsAdminUser: false,
needsPrimaryDriverId: false,
roles: ['user'],
displayName: 'Jane Sponsor',
},
{
email: 'demo.owner@example.com',
password: 'Demo1234!',
needsAdminUser: true,
needsPrimaryDriverId: true,
roles: ['owner'],
displayName: 'Alice Owner',
},
{
email: 'demo.steward@example.com',
password: 'Demo1234!',
needsAdminUser: true,
needsPrimaryDriverId: true,
roles: ['user'],
displayName: 'Bob Steward',
},
{
email: 'demo.admin@example.com',
password: 'Demo1234!',
needsAdminUser: true,
needsPrimaryDriverId: true,
roles: ['admin'],
displayName: 'Charlie Admin',
},
{
email: 'demo.systemowner@example.com',
password: 'Demo1234!',
needsAdminUser: true,
needsPrimaryDriverId: true,
roles: ['admin'],
displayName: 'Diana SystemOwner',
},
{
email: 'demo.superadmin@example.com',
password: 'Demo1234!',
needsAdminUser: true,
needsPrimaryDriverId: true,
roles: ['admin'],
displayName: 'Edward SuperAdmin',
},
];
constructor(
private readonly logger: Logger,
private readonly authRepository: IAuthRepository,
private readonly passwordHashingService: IPasswordHashingService,
private readonly adminUserRepository: IAdminUserRepository,
) {}
private getApiPersistence(): 'postgres' | 'inmemory' {
const configured = process.env.GRIDPILOT_API_PERSISTENCE?.toLowerCase();
if (configured === 'postgres' || configured === 'inmemory') {
return configured;
}
if (process.env.NODE_ENV === 'test') {
return 'inmemory';
}
return process.env.DATABASE_URL ? 'postgres' : 'inmemory';
}
private generateDeterministicId(seedKey: string, persistence: 'postgres' | 'inmemory'): string {
if (persistence === 'postgres') {
return stableUuidFromSeedKey(seedKey);
}
return seedKey;
}
private generatePrimaryDriverId(email: string, persistence: 'postgres' | 'inmemory'): string {
// Use the email as the seed for the primary driver ID
const seedKey = `primary-driver-${email}`;
return this.generateDeterministicId(seedKey, persistence);
}
async execute(): Promise<void> {
const persistence = this.getApiPersistence();
// Check for force reseed via environment variable
const forceReseedRaw = process.env.GRIDPILOT_API_FORCE_RESEED;
const forceReseed = forceReseedRaw !== undefined && forceReseedRaw !== '0' && forceReseedRaw.toLowerCase() !== 'false';
this.logger.info(
`[Bootstrap] Demo users seed precheck: forceReseed=${forceReseed}, persistence=${persistence}`,
);
// Check if all demo users already exist
let allUsersExist = true;
for (const spec of this.demoUserSpecs) {
const existingUser = await this.authRepository.findByEmail(EmailAddress.create(spec.email));
if (!existingUser) {
allUsersExist = false;
break;
}
// Also check for admin users if needed
if (spec.needsAdminUser) {
const existingAdmin = await this.adminUserRepository.findByEmail(Email.create(spec.email));
if (!existingAdmin) {
allUsersExist = false;
break;
}
}
}
if (allUsersExist && !forceReseed) {
this.logger.info('[Bootstrap] Demo users already exist, skipping');
return;
}
if (forceReseed) {
this.logger.info('[Bootstrap] Force reseed enabled - updating existing demo users');
} else {
this.logger.info('[Bootstrap] Starting demo users seed');
}
// Create or update each demo user
for (const spec of this.demoUserSpecs) {
await this.createOrUpdateDemoUser(spec, persistence);
}
this.logger.info(
`[Bootstrap] Demo users seed completed: ${this.demoUserSpecs.length} users processed`,
);
}
private async createOrUpdateDemoUser(spec: DemoUserSpec, persistence: 'postgres' | 'inmemory'): Promise<void> {
const userId = this.generateDeterministicId(`demo-user-${spec.email}`, persistence);
// Check if user exists
const existingUser = await this.authRepository.findByEmail(EmailAddress.create(spec.email));
// Hash the password
const passwordHash = await this.passwordHashingService.hash(spec.password);
if (existingUser) {
// Update existing user
const rehydrateProps: {
id: string;
displayName: string;
email?: string;
passwordHash?: PasswordHash;
primaryDriverId?: string;
} = {
id: userId,
displayName: spec.displayName,
email: spec.email,
passwordHash: PasswordHash.fromHash(passwordHash),
};
if (spec.needsPrimaryDriverId) {
rehydrateProps.primaryDriverId = this.generatePrimaryDriverId(spec.email, persistence);
}
const updatedUser = User.rehydrate(rehydrateProps);
await this.authRepository.save(updatedUser);
this.logger.debug(`[Bootstrap] Updated demo user: ${spec.email}`);
} else {
// Create new user
const createProps: {
id: UserId;
displayName: string;
email?: string;
passwordHash?: PasswordHash;
primaryDriverId?: string;
} = {
id: UserId.fromString(userId),
displayName: spec.displayName,
email: spec.email,
passwordHash: PasswordHash.fromHash(passwordHash),
};
if (spec.needsPrimaryDriverId) {
createProps.primaryDriverId = this.generatePrimaryDriverId(spec.email, persistence);
}
const user = User.create(createProps);
await this.authRepository.save(user);
this.logger.debug(`[Bootstrap] Created demo user: ${spec.email}`);
}
// Handle admin user if needed
if (spec.needsAdminUser) {
const adminUserId = this.generateDeterministicId(`demo-admin-${spec.email}`, persistence);
const existingAdmin = await this.adminUserRepository.findByEmail(Email.create(spec.email));
if (existingAdmin) {
// Admin user exists, no update needed for now
this.logger.debug(`[Bootstrap] Admin user already exists: ${spec.email}`);
} else {
// Create admin user
const adminCreateProps: {
id: string;
email: string;
roles: string[];
status: string;
displayName: string;
primaryDriverId?: string;
} = {
id: adminUserId,
email: spec.email,
roles: spec.roles,
status: 'active',
displayName: spec.displayName,
};
if (spec.needsPrimaryDriverId) {
adminCreateProps.primaryDriverId = this.generatePrimaryDriverId(spec.email, persistence);
}
const adminUser = AdminUser.create(adminCreateProps);
await this.adminUserRepository.create(adminUser);
this.logger.debug(`[Bootstrap] Created admin user: ${spec.email} with roles: ${spec.roles.join(', ')}`);
}
}
}
}

View File

@@ -24,6 +24,9 @@ import type { ISocialGraphRepository } from '@core/social/domain/repositories/IS
import type { IDriverStatsRepository } from '@core/racing/domain/repositories/IDriverStatsRepository';
import type { ITeamStatsRepository, TeamStats } from '@core/racing/domain/repositories/ITeamStatsRepository';
import type { IMediaRepository } from '@core/racing/domain/repositories/IMediaRepository';
import type { IAuthRepository } from '@core/identity/domain/repositories/IAuthRepository';
import type { IPasswordHashingService } from '@core/identity/domain/services/PasswordHashingService';
import type { IAdminUserRepository } from '@core/admin/domain/repositories/IAdminUserRepository';
import { createRacingSeed } from './racing/RacingSeed';
import { seedId } from './racing/SeedIdHelper';
import { Driver } from '@core/racing/domain/entities/Driver';
@@ -56,6 +59,10 @@ export type RacingSeedDependencies = {
driverStatsRepository: IDriverStatsRepository;
teamStatsRepository: ITeamStatsRepository;
mediaRepository: IMediaRepository;
// Identity dependencies for demo user seed
authRepository: IAuthRepository;
passwordHashingService: IPasswordHashingService;
adminUserRepository: IAdminUserRepository;
};
export class SeedRacingData {
@@ -766,4 +773,4 @@ export class SeedRacingData {
return 'club-default';
}
}
}