refactor: restructure to monorepo with apps and packages directories - Move companion app to apps/companion with electron-vite - Move domain/application/infrastructure to packages/ - Fix ELECTRON_RUN_AS_NODE env var issue for VS Code terminal - Remove legacy esbuild bundler (replaced by electron-vite) - Update workspace scripts in root package.json
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
import { IAutomationEngine, ValidationResult } from '../../../packages/application/ports/IAutomationEngine';
|
||||
import { HostedSessionConfig } from '../../../packages/domain/entities/HostedSessionConfig';
|
||||
import { StepId } from '../../../packages/domain/value-objects/StepId';
|
||||
import { IBrowserAutomation } from '../../../packages/application/ports/IBrowserAutomation';
|
||||
import { ISessionRepository } from '../../../packages/application/ports/ISessionRepository';
|
||||
import { getStepName } from './selectors/IRacingSelectorMap';
|
||||
|
||||
export class MockAutomationEngineAdapter implements IAutomationEngine {
|
||||
private automationInterval: NodeJS.Timeout | null = null;
|
||||
|
||||
constructor(
|
||||
private readonly browserAutomation: IBrowserAutomation,
|
||||
private readonly sessionRepository: ISessionRepository
|
||||
) {}
|
||||
|
||||
async validateConfiguration(config: HostedSessionConfig): Promise<ValidationResult> {
|
||||
if (!config.sessionName || config.sessionName.trim() === '') {
|
||||
return { isValid: false, error: 'Session name is required' };
|
||||
}
|
||||
if (!config.trackId || config.trackId.trim() === '') {
|
||||
return { isValid: false, error: 'Track ID is required' };
|
||||
}
|
||||
if (!config.carIds || config.carIds.length === 0) {
|
||||
return { isValid: false, error: 'At least one car must be selected' };
|
||||
}
|
||||
return { isValid: true };
|
||||
}
|
||||
|
||||
async executeStep(stepId: StepId, config: HostedSessionConfig): Promise<void> {
|
||||
const sessions = await this.sessionRepository.findAll();
|
||||
const session = sessions[0];
|
||||
if (!session) {
|
||||
throw new Error('No active session found');
|
||||
}
|
||||
|
||||
// Start session if it's at step 1 and pending
|
||||
if (session.state.isPending() && stepId.value === 1) {
|
||||
session.start();
|
||||
await this.sessionRepository.update(session);
|
||||
|
||||
// Start automated progression
|
||||
this.startAutomation(config);
|
||||
}
|
||||
}
|
||||
|
||||
private startAutomation(config: HostedSessionConfig): void {
|
||||
this.automationInterval = setInterval(async () => {
|
||||
try {
|
||||
const sessions = await this.sessionRepository.findAll();
|
||||
const session = sessions[0];
|
||||
|
||||
if (!session || !session.state.isInProgress()) {
|
||||
if (this.automationInterval) {
|
||||
clearInterval(this.automationInterval);
|
||||
this.automationInterval = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const currentStep = session.currentStep;
|
||||
|
||||
// Execute current step using the browser automation
|
||||
if (this.browserAutomation.executeStep) {
|
||||
// Use real workflow automation with IRacingSelectorMap
|
||||
const result = await this.browserAutomation.executeStep(currentStep, config as Record<string, unknown>);
|
||||
if (!result.success) {
|
||||
console.error(`Step ${currentStep.value} (${getStepName(currentStep.value)}) failed:`, result.error);
|
||||
// Continue anyway for now - in production we might want to pause or retry
|
||||
}
|
||||
} else {
|
||||
// Fallback for adapters without executeStep (e.g., MockBrowserAutomationAdapter)
|
||||
await this.browserAutomation.navigateToPage(`step-${currentStep.value}`);
|
||||
}
|
||||
|
||||
// Transition to next step if not final
|
||||
if (!currentStep.isFinalStep()) {
|
||||
session.transitionToStep(currentStep.next());
|
||||
await this.sessionRepository.update(session);
|
||||
} else {
|
||||
// Stop at step 18
|
||||
if (this.automationInterval) {
|
||||
clearInterval(this.automationInterval);
|
||||
this.automationInterval = null;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Automation error:', error);
|
||||
if (this.automationInterval) {
|
||||
clearInterval(this.automationInterval);
|
||||
this.automationInterval = null;
|
||||
}
|
||||
}
|
||||
}, 500); // Execute each step every 500ms
|
||||
}
|
||||
|
||||
public stopAutomation(): void {
|
||||
if (this.automationInterval) {
|
||||
clearInterval(this.automationInterval);
|
||||
this.automationInterval = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user