view models

This commit is contained in:
2025-12-18 14:04:31 +01:00
parent 4f99098b32
commit 61f675d991
9 changed files with 95 additions and 19 deletions

View File

@@ -0,0 +1,8 @@
import { ErrorReporter } from "@core/shared/application";
export class ConsoleErrorReporter implements ErrorReporter {
report(error: Error, context?: unknown): void {
const timestamp = new Date().toISOString();
console.error(`[${timestamp}] Error reported:`, error.message, { error, context });
}
}

View File

@@ -1,20 +1,26 @@
import { Logger } from "@core/shared/application";
export class ConsoleLogger implements Logger {
debug(message: string, ...args: any[]): void {
console.debug(message, ...args);
private formatMessage(level: string, message: string, context?: unknown): string {
const timestamp = new Date().toISOString();
const contextStr = context ? ` | ${JSON.stringify(context)}` : '';
return `[${timestamp}] ${level.toUpperCase()}: ${message}${contextStr}`;
}
info(message: string, ...args: any[]): void {
console.info(message, ...args);
debug(message: string, context?: unknown): void {
console.debug(this.formatMessage('debug', message, context));
}
warn(message: string, ...args: any[]): void {
console.warn(message, ...args);
info(message: string, context?: unknown): void {
console.info(this.formatMessage('info', message, context));
}
error(message: string, ...args: any[]): void {
console.error(message, ...args);
warn(message: string, context?: unknown): void {
console.warn(this.formatMessage('warn', message, context));
}
error(message: string, error?: Error, context?: unknown): void {
const errorStr = error ? ` | Error: ${error.message}` : '';
console.error(this.formatMessage('error', message, context) + errorStr);
}
}

View File

@@ -5,14 +5,23 @@
* error handling, and authentication.
*/
import { Logger } from '../../interfaces/Logger';
import { ErrorReporter } from '../../interfaces/ErrorReporter';
export class BaseApiClient {
private baseUrl: string;
private errorReporter: ErrorReporter;
private logger: Logger;
constructor(baseUrl: string) {
constructor(baseUrl: string, errorReporter: ErrorReporter, logger: Logger) {
this.baseUrl = baseUrl;
this.errorReporter = errorReporter;
this.logger = logger;
}
protected async request<T>(method: string, path: string, data?: object): Promise<T> {
this.logger.info(`${method} ${path}`);
const headers: HeadersInit = {
'Content-Type': 'application/json',
};
@@ -36,7 +45,9 @@ export class BaseApiClient {
} catch {
// Keep default error message
}
throw new Error(errorData.message || `API request failed with status ${response.status}`);
const error = new Error(errorData.message || `API request failed with status ${response.status}`);
this.errorReporter.report(error);
throw error;
}
const text = await response.text();

View File

@@ -0,0 +1,8 @@
import { ErrorReporter } from '../../interfaces/ErrorReporter';
export class ConsoleErrorReporter implements ErrorReporter {
report(error: Error, context?: unknown): void {
const timestamp = new Date().toISOString();
console.error(`[${timestamp}] Error reported:`, error.message, { error, context });
}
}

View File

@@ -0,0 +1,26 @@
import { Logger } from '../../interfaces/Logger';
export class ConsoleLogger implements Logger {
private formatMessage(level: string, message: string, context?: unknown): string {
const timestamp = new Date().toISOString();
const contextStr = context ? ` | ${JSON.stringify(context)}` : '';
return `[${timestamp}] ${level.toUpperCase()}: ${message}${contextStr}`;
}
debug(message: string, context?: unknown): void {
console.debug(this.formatMessage('debug', message, context));
}
info(message: string, context?: unknown): void {
console.info(this.formatMessage('info', message, context));
}
warn(message: string, context?: unknown): void {
console.warn(this.formatMessage('warn', message, context));
}
error(message: string, error?: Error, context?: unknown): void {
const errorStr = error ? ` | Error: ${error.message}` : '';
console.error(this.formatMessage('error', message, context) + errorStr);
}
}

View File

@@ -0,0 +1,3 @@
export interface ErrorReporter {
report(error: Error, context?: unknown): void;
}

View File

@@ -0,0 +1,6 @@
export interface Logger {
debug(message: string, context?: unknown): void;
info(message: string, context?: unknown): void;
warn(message: string, context?: unknown): void;
error(message: string, error?: Error, context?: unknown): void;
}

View File

@@ -7,6 +7,8 @@ import { PaymentsApiClient } from '../api/payments/PaymentsApiClient';
import { AuthApiClient } from '../api/auth/AuthApiClient';
import { AnalyticsApiClient } from '../api/analytics/AnalyticsApiClient';
import { MediaApiClient } from '../api/media/MediaApiClient';
import { ConsoleErrorReporter } from '../infrastructure/logging/ConsoleErrorReporter';
import { ConsoleLogger } from '../infrastructure/logging/ConsoleLogger';
// Services
import { RaceService } from './races/RaceService';
@@ -37,6 +39,9 @@ import { SessionService } from './auth/SessionService';
* Services now directly instantiate View Models instead of using Presenters.
*/
export class ServiceFactory {
private readonly errorReporter = new ConsoleErrorReporter();
private readonly logger = new ConsoleLogger();
private readonly apiClients: {
races: RacesApiClient;
drivers: DriversApiClient;
@@ -52,15 +57,15 @@ export class ServiceFactory {
constructor(baseUrl: string) {
// Initialize API clients
this.apiClients = {
races: new RacesApiClient(baseUrl),
drivers: new DriversApiClient(baseUrl),
teams: new TeamsApiClient(baseUrl),
leagues: new LeaguesApiClient(baseUrl),
sponsors: new SponsorsApiClient(baseUrl),
payments: new PaymentsApiClient(baseUrl),
auth: new AuthApiClient(baseUrl),
analytics: new AnalyticsApiClient(baseUrl),
media: new MediaApiClient(baseUrl),
races: new RacesApiClient(baseUrl, this.errorReporter, this.logger),
drivers: new DriversApiClient(baseUrl, this.errorReporter, this.logger),
teams: new TeamsApiClient(baseUrl, this.errorReporter, this.logger),
leagues: new LeaguesApiClient(baseUrl, this.errorReporter, this.logger),
sponsors: new SponsorsApiClient(baseUrl, this.errorReporter, this.logger),
payments: new PaymentsApiClient(baseUrl, this.errorReporter, this.logger),
auth: new AuthApiClient(baseUrl, this.errorReporter, this.logger),
analytics: new AnalyticsApiClient(baseUrl, this.errorReporter, this.logger),
media: new MediaApiClient(baseUrl, this.errorReporter, this.logger),
};
}

View File

@@ -0,0 +1,3 @@
export interface ErrorReporter {
report(error: Error, context?: unknown): void;
}