wip
This commit is contained in:
@@ -11,12 +11,14 @@ import type { AutomationEnginePort } from '@gridpilot/automation/application/por
|
||||
import type { AuthenticationServicePort } from '@gridpilot/automation/application/ports/AuthenticationServicePort';
|
||||
import type { LoggerPort } from '@gridpilot/automation/application/ports/LoggerPort';
|
||||
import type { OverlaySyncPort } from '@gridpilot/automation/application/ports/OverlaySyncPort';
|
||||
import type { CheckoutServicePort } from '@gridpilot/automation/application/ports/CheckoutServicePort';
|
||||
import { StartAutomationSessionUseCase } from '@gridpilot/automation/application/use-cases/StartAutomationSessionUseCase';
|
||||
import { CheckAuthenticationUseCase } from '@gridpilot/automation/application/use-cases/CheckAuthenticationUseCase';
|
||||
import { InitiateLoginUseCase } from '@gridpilot/automation/application/use-cases/InitiateLoginUseCase';
|
||||
import { ClearSessionUseCase } from '@gridpilot/automation/application/use-cases/ClearSessionUseCase';
|
||||
import { ConfirmCheckoutUseCase } from '@gridpilot/automation/application/use-cases/ConfirmCheckoutUseCase';
|
||||
import { OverlaySyncService } from '@gridpilot/automation/application/services/OverlaySyncService';
|
||||
import type { IAutomationLifecycleEmitter } from '@gridpilot/automation/infrastructure/adapters/IAutomationLifecycleEmitter';
|
||||
|
||||
// Infrastructure
|
||||
import { InMemorySessionRepository } from '@gridpilot/automation/infrastructure/repositories/InMemorySessionRepository';
|
||||
@@ -187,13 +189,19 @@ export function configureDIContainer(): void {
|
||||
browserAutomation
|
||||
);
|
||||
|
||||
// Checkout Service (singleton, backed by browser automation)
|
||||
container.registerInstance<CheckoutServicePort>(
|
||||
DI_TOKENS.CheckoutService,
|
||||
browserAutomation as unknown as CheckoutServicePort
|
||||
);
|
||||
|
||||
// Automation Engine (singleton)
|
||||
const sessionRepository = container.resolve<SessionRepositoryPort>(DI_TOKENS.SessionRepository);
|
||||
let automationEngine: AutomationEnginePort;
|
||||
|
||||
if (fixtureMode) {
|
||||
automationEngine = new AutomationEngineAdapter(
|
||||
browserAutomation as any,
|
||||
browserAutomation,
|
||||
sessionRepository
|
||||
);
|
||||
} else {
|
||||
@@ -247,16 +255,16 @@ export function configureDIContainer(): void {
|
||||
}
|
||||
|
||||
// Overlay Sync Service - create singleton instance directly
|
||||
const lifecycleEmitter = browserAutomation as any;
|
||||
const lifecycleEmitter = browserAutomation as unknown as IAutomationLifecycleEmitter;
|
||||
const publisher = {
|
||||
publish: async (_event: any) => {
|
||||
publish: async (event: unknown) => {
|
||||
try {
|
||||
logger.debug?.('OverlaySyncPublisher.publish', _event);
|
||||
logger.debug?.('OverlaySyncPublisher.publish', { event });
|
||||
} catch {
|
||||
// swallow
|
||||
}
|
||||
},
|
||||
} as any;
|
||||
};
|
||||
const overlaySyncService = new OverlaySyncService({
|
||||
lifecycleEmitter,
|
||||
publisher,
|
||||
|
||||
@@ -13,6 +13,7 @@ import type { IBrowserAutomation } from '@gridpilot/automation/application/ports
|
||||
import type { AutomationEnginePort } from '@gridpilot/automation/application/ports/AutomationEnginePort';
|
||||
import type { AuthenticationServicePort } from '@gridpilot/automation/application/ports/AuthenticationServicePort';
|
||||
import type { CheckoutConfirmationPort } from '@gridpilot/automation/application/ports/CheckoutConfirmationPort';
|
||||
import type { CheckoutServicePort } from '@gridpilot/automation/application/ports/CheckoutServicePort';
|
||||
import type { LoggerPort } from '@gridpilot/automation/application/ports/LoggerPort';
|
||||
import type { OverlaySyncPort } from '@gridpilot/automation/application/ports/OverlaySyncPort';
|
||||
|
||||
@@ -145,9 +146,9 @@ export class DIContainer {
|
||||
|
||||
public setConfirmCheckoutUseCase(checkoutConfirmationPort: CheckoutConfirmationPort): void {
|
||||
this.ensureInitialized();
|
||||
const browserAutomation = getDIContainer().resolve<IBrowserAutomation>(DI_TOKENS.BrowserAutomation);
|
||||
const checkoutService = getDIContainer().resolve<CheckoutServicePort>(DI_TOKENS.CheckoutService);
|
||||
this.confirmCheckoutUseCase = new ConfirmCheckoutUseCase(
|
||||
browserAutomation as any,
|
||||
checkoutService,
|
||||
checkoutConfirmationPort
|
||||
);
|
||||
}
|
||||
@@ -188,7 +189,7 @@ export class DIContainer {
|
||||
new Error(result.error || 'Unknown error'),
|
||||
{ mode: this.automationMode }
|
||||
);
|
||||
return { success: false, error: result.error };
|
||||
return { success: false, error: result.error ?? 'Unknown error' };
|
||||
}
|
||||
|
||||
const isConnected = playwrightAdapter.isConnected();
|
||||
|
||||
@@ -27,6 +27,7 @@ export const DI_TOKENS = {
|
||||
|
||||
// Services
|
||||
OverlaySyncPort: Symbol.for('OverlaySyncPort'),
|
||||
CheckoutService: Symbol.for('CheckoutServicePort'),
|
||||
|
||||
// Infrastructure
|
||||
FixtureServer: Symbol.for('FixtureServer'),
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { ipcMain } from 'electron';
|
||||
import type { BrowserWindow, IpcMainInvokeEvent } from 'electron';
|
||||
import { DIContainer } from './di-container';
|
||||
import type { HostedSessionConfig } from '@/packages/domain/entities/HostedSessionConfig';
|
||||
import { StepId } from '@/packages/domain/value-objects/StepId';
|
||||
import { AuthenticationState } from '@/packages/domain/value-objects/AuthenticationState';
|
||||
import { ElectronCheckoutConfirmationAdapter } from '@/packages/infrastructure/adapters/ipc/ElectronCheckoutConfirmationAdapter';
|
||||
import type { HostedSessionConfig } from 'packages/automation/domain/types/HostedSessionConfig';
|
||||
import { StepId } from 'packages/automation/domain/value-objects/StepId';
|
||||
import { AuthenticationState } from 'packages/automation/domain/value-objects/AuthenticationState';
|
||||
import { ElectronCheckoutConfirmationAdapter } from 'packages/automation/infrastructure/adapters/ipc/ElectronCheckoutConfirmationAdapter';
|
||||
import type { OverlayAction } from 'packages/automation/application/ports/OverlaySyncPort';
|
||||
import type { IAutomationLifecycleEmitter } from 'packages/automation/infrastructure/adapters/IAutomationLifecycleEmitter';
|
||||
|
||||
let progressMonitorInterval: NodeJS.Timeout | null = null;
|
||||
let lifecycleSubscribed = false;
|
||||
@@ -95,8 +97,8 @@ export function setupIpcHandlers(mainWindow: BrowserWindow): void {
|
||||
}
|
||||
|
||||
// Call confirmLoginComplete on the adapter if it exists
|
||||
if ('confirmLoginComplete' in authService) {
|
||||
const result = await (authService as any).confirmLoginComplete();
|
||||
if ('confirmLoginComplete' in authService && typeof authService.confirmLoginComplete === 'function') {
|
||||
const result = await authService.confirmLoginComplete();
|
||||
if (result.isErr()) {
|
||||
logger.error('Confirm login failed', result.unwrapErr());
|
||||
return { success: false, error: result.unwrapErr().message };
|
||||
@@ -334,7 +336,7 @@ export function setupIpcHandlers(mainWindow: BrowserWindow): void {
|
||||
// Ensure runtime automation wiring reflects the new browser mode
|
||||
if ('refreshBrowserAutomation' in container) {
|
||||
// Call method to refresh adapters/use-cases that depend on browser mode
|
||||
(container as any).refreshBrowserAutomation();
|
||||
container.refreshBrowserAutomation();
|
||||
}
|
||||
logger.info('Browser mode updated', { mode });
|
||||
return { success: true, mode };
|
||||
@@ -349,9 +351,9 @@ export function setupIpcHandlers(mainWindow: BrowserWindow): void {
|
||||
});
|
||||
|
||||
// Handle overlay action requests from renderer and forward to the OverlaySyncService
|
||||
ipcMain.handle('overlay-action-request', async (_event: IpcMainInvokeEvent, action: any) => {
|
||||
ipcMain.handle('overlay-action-request', async (_event: IpcMainInvokeEvent, action: OverlayAction) => {
|
||||
try {
|
||||
const overlayPort = (container as any).getOverlaySyncPort ? container.getOverlaySyncPort() : null;
|
||||
const overlayPort = 'getOverlaySyncPort' in container ? container.getOverlaySyncPort() : null;
|
||||
if (!overlayPort) {
|
||||
logger.warn('OverlaySyncPort not available');
|
||||
return { id: action?.id ?? 'unknown', status: 'failed', reason: 'OverlaySyncPort not available' };
|
||||
@@ -361,16 +363,20 @@ export function setupIpcHandlers(mainWindow: BrowserWindow): void {
|
||||
} catch (e) {
|
||||
const err = e instanceof Error ? e : new Error(String(e));
|
||||
logger.error('Overlay action request failed', err);
|
||||
return { id: action?.id ?? 'unknown', status: 'failed', reason: err.message };
|
||||
const id = typeof action === 'object' && action !== null && 'id' in action
|
||||
? // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(action as { id?: string }).id ?? 'unknown'
|
||||
: 'unknown';
|
||||
return { id, status: 'failed', reason: err.message };
|
||||
}
|
||||
});
|
||||
|
||||
// Subscribe to automation adapter lifecycle events and relay to renderer
|
||||
try {
|
||||
if (!lifecycleSubscribed) {
|
||||
const browserAutomation = container.getBrowserAutomation() as any;
|
||||
if (browserAutomation && typeof browserAutomation.onLifecycle === 'function') {
|
||||
browserAutomation.onLifecycle((ev: any) => {
|
||||
const lifecycleEmitter = container.getBrowserAutomation() as unknown as IAutomationLifecycleEmitter;
|
||||
if (typeof lifecycleEmitter.onLifecycle === 'function') {
|
||||
lifecycleEmitter.onLifecycle((ev) => {
|
||||
try {
|
||||
if (mainWindow && mainWindow.webContents) {
|
||||
mainWindow.webContents.send('automation-event', ev);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { contextBridge, ipcRenderer } from 'electron';
|
||||
import type { HostedSessionConfig } from '../../../packages/automation/domain/types/HostedSessionConfig';
|
||||
import type { AuthenticationState } from '../../../packages/domain/value-objects/AuthenticationState';
|
||||
import type { AuthenticationState } from '../../../packages/automation/domain/value-objects/AuthenticationState';
|
||||
|
||||
export interface AuthStatusEvent {
|
||||
state: AuthenticationState;
|
||||
|
||||
Reference in New Issue
Block a user