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:
30
packages/application/ports/AutomationResults.ts
Normal file
30
packages/application/ports/AutomationResults.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
export interface AutomationResult {
|
||||
success: boolean;
|
||||
error?: string;
|
||||
metadata?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface NavigationResult extends AutomationResult {
|
||||
url: string;
|
||||
loadTime: number;
|
||||
}
|
||||
|
||||
export interface FormFillResult extends AutomationResult {
|
||||
fieldName: string;
|
||||
valueSet: string;
|
||||
}
|
||||
|
||||
export interface ClickResult extends AutomationResult {
|
||||
target: string;
|
||||
}
|
||||
|
||||
export interface WaitResult extends AutomationResult {
|
||||
target: string;
|
||||
waitedMs: number;
|
||||
found: boolean;
|
||||
}
|
||||
|
||||
export interface ModalResult extends AutomationResult {
|
||||
stepId: number;
|
||||
action: string;
|
||||
}
|
||||
12
packages/application/ports/IAutomationEngine.ts
Normal file
12
packages/application/ports/IAutomationEngine.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { HostedSessionConfig } from '../../domain/entities/HostedSessionConfig';
|
||||
import { StepId } from '../../domain/value-objects/StepId';
|
||||
|
||||
export interface ValidationResult {
|
||||
isValid: boolean;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export interface IAutomationEngine {
|
||||
validateConfiguration(config: HostedSessionConfig): Promise<ValidationResult>;
|
||||
executeStep(stepId: StepId, config: HostedSessionConfig): Promise<void>;
|
||||
}
|
||||
31
packages/application/ports/IBrowserAutomation.ts
Normal file
31
packages/application/ports/IBrowserAutomation.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { StepId } from '../../domain/value-objects/StepId';
|
||||
import {
|
||||
NavigationResult,
|
||||
FormFillResult,
|
||||
ClickResult,
|
||||
WaitResult,
|
||||
ModalResult,
|
||||
AutomationResult,
|
||||
} from './AutomationResults';
|
||||
|
||||
export interface IBrowserAutomation {
|
||||
navigateToPage(url: string): Promise<NavigationResult>;
|
||||
fillFormField(fieldName: string, value: string): Promise<FormFillResult>;
|
||||
clickElement(selector: string): Promise<ClickResult>;
|
||||
waitForElement(selector: string, maxWaitMs?: number): Promise<WaitResult>;
|
||||
handleModal(stepId: StepId, action: string): Promise<ModalResult>;
|
||||
|
||||
/**
|
||||
* Execute a complete workflow step with all required browser operations.
|
||||
* Uses IRacingSelectorMap to locate elements and performs appropriate actions.
|
||||
*
|
||||
* @param stepId - The step to execute (1-18)
|
||||
* @param config - Session configuration with form field values
|
||||
* @returns AutomationResult with success/failure and metadata
|
||||
*/
|
||||
executeStep?(stepId: StepId, config: Record<string, unknown>): Promise<AutomationResult>;
|
||||
|
||||
connect?(): Promise<void>;
|
||||
disconnect?(): Promise<void>;
|
||||
isConnected?(): boolean;
|
||||
}
|
||||
11
packages/application/ports/ISessionRepository.ts
Normal file
11
packages/application/ports/ISessionRepository.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { AutomationSession } from '../../domain/entities/AutomationSession';
|
||||
import { SessionStateValue } from '../../domain/value-objects/SessionState';
|
||||
|
||||
export interface ISessionRepository {
|
||||
save(session: AutomationSession): Promise<void>;
|
||||
findById(id: string): Promise<AutomationSession | null>;
|
||||
update(session: AutomationSession): Promise<void>;
|
||||
delete(id: string): Promise<void>;
|
||||
findAll(): Promise<AutomationSession[]>;
|
||||
findByState(state: SessionStateValue): Promise<AutomationSession[]>;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import { AutomationSession } from '../../domain/entities/AutomationSession';
|
||||
import { HostedSessionConfig } from '../../domain/entities/HostedSessionConfig';
|
||||
import { IAutomationEngine } from '../ports/IAutomationEngine';
|
||||
import { IBrowserAutomation } from '../ports/IBrowserAutomation';
|
||||
import { ISessionRepository } from '../ports/ISessionRepository';
|
||||
|
||||
export interface SessionDTO {
|
||||
sessionId: string;
|
||||
state: string;
|
||||
currentStep: number;
|
||||
config: HostedSessionConfig;
|
||||
startedAt?: Date;
|
||||
completedAt?: Date;
|
||||
errorMessage?: string;
|
||||
}
|
||||
|
||||
export class StartAutomationSessionUseCase {
|
||||
constructor(
|
||||
private readonly automationEngine: IAutomationEngine,
|
||||
private readonly browserAutomation: IBrowserAutomation,
|
||||
private readonly sessionRepository: ISessionRepository
|
||||
) {}
|
||||
|
||||
async execute(config: HostedSessionConfig): Promise<SessionDTO> {
|
||||
const session = AutomationSession.create(config);
|
||||
|
||||
const validationResult = await this.automationEngine.validateConfiguration(config);
|
||||
if (!validationResult.isValid) {
|
||||
throw new Error(validationResult.error);
|
||||
}
|
||||
|
||||
await this.sessionRepository.save(session);
|
||||
|
||||
return {
|
||||
sessionId: session.id,
|
||||
state: session.state.value,
|
||||
currentStep: session.currentStep.value,
|
||||
config: session.config,
|
||||
startedAt: session.startedAt,
|
||||
completedAt: session.completedAt,
|
||||
errorMessage: session.errorMessage,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user