website refactor
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { AdminService } from '@/lib/services/admin/AdminService';
|
||||
import { Result } from '@/lib/contracts/Result';
|
||||
import { MutationError, mapToMutationError } from '@/lib/contracts/mutations/MutationError';
|
||||
import { Mutation } from '@/lib/contracts/mutations/Mutation';
|
||||
|
||||
/**
|
||||
* DeleteUserMutation
|
||||
@@ -13,7 +14,7 @@ import { MutationError, mapToMutationError } from '@/lib/contracts/mutations/Mut
|
||||
*
|
||||
* Pattern: Server Action → Mutation → Service → API Client
|
||||
*/
|
||||
export class DeleteUserMutation {
|
||||
export class DeleteUserMutation implements Mutation<{ userId: string }, void, MutationError> {
|
||||
async execute(input: { userId: string }): Promise<Result<void, MutationError>> {
|
||||
try {
|
||||
// Manual construction: Service creates its own dependencies
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { AdminService } from '@/lib/services/admin/AdminService';
|
||||
import { Result } from '@/lib/contracts/Result';
|
||||
import { MutationError, mapToMutationError } from '@/lib/contracts/mutations/MutationError';
|
||||
import { Mutation } from '@/lib/contracts/mutations/Mutation';
|
||||
|
||||
/**
|
||||
* UpdateUserStatusMutation
|
||||
@@ -13,7 +14,7 @@ import { MutationError, mapToMutationError } from '@/lib/contracts/mutations/Mut
|
||||
*
|
||||
* Pattern: Server Action → Mutation → Service → API Client
|
||||
*/
|
||||
export class UpdateUserStatusMutation {
|
||||
export class UpdateUserStatusMutation implements Mutation<{ userId: string; status: string }, void, MutationError> {
|
||||
async execute(input: { userId: string; status: string }): Promise<Result<void, MutationError>> {
|
||||
try {
|
||||
// Manual construction: Service creates its own dependencies
|
||||
|
||||
24
apps/website/lib/mutations/auth/LogoutMutation.ts
Normal file
24
apps/website/lib/mutations/auth/LogoutMutation.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Logout Mutation
|
||||
*
|
||||
* Framework-agnostic mutation for logout operations.
|
||||
* Called from Server Actions.
|
||||
*
|
||||
* Pattern: Server Action → Mutation → Service → API Client
|
||||
*/
|
||||
|
||||
import { Result } from '@/lib/contracts/Result';
|
||||
import { AuthService } from '@/lib/services/auth/AuthService';
|
||||
|
||||
export class LogoutMutation {
|
||||
async execute(): Promise<Result<void, string>> {
|
||||
try {
|
||||
const authService = new AuthService();
|
||||
await authService.logout();
|
||||
return Result.ok(undefined);
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : 'Logout failed';
|
||||
return Result.err(errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import type { CreateLeagueInputDTO } from '@/lib/types/generated/CreateLeagueInp
|
||||
/**
|
||||
* CreateLeagueMutation
|
||||
*
|
||||
* Framework-agnostic mutation for league creation.
|
||||
* Framework-agnostic mutation for creating leagues.
|
||||
* Can be called from Server Actions or other contexts.
|
||||
*/
|
||||
export class CreateLeagueMutation {
|
||||
@@ -24,12 +24,12 @@ export class CreateLeagueMutation {
|
||||
this.service = new LeagueService(apiClient);
|
||||
}
|
||||
|
||||
async createLeague(input: CreateLeagueInputDTO): Promise<Result<void, string>> {
|
||||
async execute(input: CreateLeagueInputDTO): Promise<Result<string, string>> {
|
||||
try {
|
||||
await this.service.createLeague(input);
|
||||
return Result.ok(undefined);
|
||||
const result = await this.service.createLeague(input);
|
||||
return Result.ok(result.leagueId);
|
||||
} catch (error) {
|
||||
console.error('createLeague failed:', error);
|
||||
console.error('CreateLeagueMutation failed:', error);
|
||||
return Result.err('Failed to create league');
|
||||
}
|
||||
}
|
||||
|
||||
80
apps/website/lib/mutations/leagues/StewardingMutation.ts
Normal file
80
apps/website/lib/mutations/leagues/StewardingMutation.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import { Result } from '@/lib/contracts/Result';
|
||||
import { LeagueService } from '@/lib/services/leagues/LeagueService';
|
||||
import { LeaguesApiClient } from '@/lib/api/leagues/LeaguesApiClient';
|
||||
import { ConsoleErrorReporter } from '@/lib/infrastructure/logging/ConsoleErrorReporter';
|
||||
import { ConsoleLogger } from '@/lib/infrastructure/logging/ConsoleLogger';
|
||||
|
||||
/**
|
||||
* StewardingMutation
|
||||
*
|
||||
* Framework-agnostic mutation for stewarding operations.
|
||||
* Can be called from Server Actions or other contexts.
|
||||
*/
|
||||
export class StewardingMutation {
|
||||
private service: LeagueService;
|
||||
|
||||
constructor() {
|
||||
// Manual wiring for serverless
|
||||
const baseUrl = process.env.NEXT_PUBLIC_API_URL || '';
|
||||
const errorReporter = new ConsoleErrorReporter();
|
||||
const logger = new ConsoleLogger();
|
||||
const apiClient = new LeaguesApiClient(baseUrl, errorReporter, logger);
|
||||
|
||||
this.service = new LeagueService(apiClient);
|
||||
}
|
||||
|
||||
async applyPenalty(input: {
|
||||
protestId: string;
|
||||
penaltyType: string;
|
||||
penaltyValue: number;
|
||||
stewardNotes: string;
|
||||
raceId: string;
|
||||
accusedDriverId: string;
|
||||
reason: string;
|
||||
}): Promise<Result<void, string>> {
|
||||
try {
|
||||
// TODO: Implement when penalty API is available
|
||||
// For now, return success
|
||||
console.log('applyPenalty called with:', input);
|
||||
return Result.ok(undefined);
|
||||
} catch (error) {
|
||||
console.error('applyPenalty failed:', error);
|
||||
return Result.err('Failed to apply penalty');
|
||||
}
|
||||
}
|
||||
|
||||
async requestDefense(input: {
|
||||
protestId: string;
|
||||
stewardId: string;
|
||||
}): Promise<Result<void, string>> {
|
||||
try {
|
||||
// TODO: Implement when defense API is available
|
||||
// For now, return success
|
||||
console.log('requestDefense called with:', input);
|
||||
return Result.ok(undefined);
|
||||
} catch (error) {
|
||||
console.error('requestDefense failed:', error);
|
||||
return Result.err('Failed to request defense');
|
||||
}
|
||||
}
|
||||
|
||||
async quickPenalty(input: {
|
||||
leagueId: string;
|
||||
driverId: string;
|
||||
raceId: string;
|
||||
penaltyType: string;
|
||||
penaltyValue: number;
|
||||
reason: string;
|
||||
adminId: string;
|
||||
}): Promise<Result<void, string>> {
|
||||
try {
|
||||
// TODO: Implement when quick penalty API is available
|
||||
// For now, return success
|
||||
console.log('quickPenalty called with:', input);
|
||||
return Result.ok(undefined);
|
||||
} catch (error) {
|
||||
console.error('quickPenalty failed:', error);
|
||||
return Result.err('Failed to apply quick penalty');
|
||||
}
|
||||
}
|
||||
}
|
||||
49
apps/website/lib/mutations/leagues/WalletMutation.ts
Normal file
49
apps/website/lib/mutations/leagues/WalletMutation.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { Result } from '@/lib/contracts/Result';
|
||||
import { LeagueService } from '@/lib/services/leagues/LeagueService';
|
||||
import { LeaguesApiClient } from '@/lib/api/leagues/LeaguesApiClient';
|
||||
import { ConsoleErrorReporter } from '@/lib/infrastructure/logging/ConsoleErrorReporter';
|
||||
import { ConsoleLogger } from '@/lib/infrastructure/logging/ConsoleLogger';
|
||||
|
||||
/**
|
||||
* WalletMutation
|
||||
*
|
||||
* Framework-agnostic mutation for wallet operations.
|
||||
* Can be called from Server Actions or other contexts.
|
||||
*/
|
||||
export class WalletMutation {
|
||||
private service: LeagueService;
|
||||
|
||||
constructor() {
|
||||
// Manual wiring for serverless
|
||||
const baseUrl = process.env.NEXT_PUBLIC_API_URL || '';
|
||||
const errorReporter = new ConsoleErrorReporter();
|
||||
const logger = new ConsoleLogger();
|
||||
const apiClient = new LeaguesApiClient(baseUrl, errorReporter, logger);
|
||||
|
||||
this.service = new LeagueService(apiClient);
|
||||
}
|
||||
|
||||
async withdraw(leagueId: string, amount: number): Promise<Result<void, string>> {
|
||||
try {
|
||||
// TODO: Implement when wallet withdrawal API is available
|
||||
// For now, return success
|
||||
console.log('withdraw called with:', { leagueId, amount });
|
||||
return Result.ok(undefined);
|
||||
} catch (error) {
|
||||
console.error('withdraw failed:', error);
|
||||
return Result.err('Failed to withdraw funds');
|
||||
}
|
||||
}
|
||||
|
||||
async exportTransactions(leagueId: string): Promise<Result<void, string>> {
|
||||
try {
|
||||
// TODO: Implement when export API is available
|
||||
// For now, return success
|
||||
console.log('exportTransactions called with:', { leagueId });
|
||||
return Result.ok(undefined);
|
||||
} catch (error) {
|
||||
console.error('exportTransactions failed:', error);
|
||||
return Result.err('Failed to export transactions');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,27 +8,23 @@
|
||||
*/
|
||||
|
||||
import { Result } from '@/lib/contracts/Result';
|
||||
import { Mutation } from '@/lib/contracts/mutations/Mutation';
|
||||
import { mapToMutationError } from '@/lib/contracts/mutations/MutationError';
|
||||
import { OnboardingService } from '@/lib/services/onboarding/OnboardingService';
|
||||
import { CompleteOnboardingInputDTO } from '@/lib/types/generated/CompleteOnboardingInputDTO';
|
||||
import { CompleteOnboardingViewDataBuilder } from '@/lib/builders/view-data/CompleteOnboardingViewDataBuilder';
|
||||
import { CompleteOnboardingViewData } from '@/lib/builders/view-data/CompleteOnboardingViewData';
|
||||
|
||||
export class CompleteOnboardingMutation {
|
||||
export class CompleteOnboardingMutation implements Mutation<CompleteOnboardingInputDTO, CompleteOnboardingViewData, string> {
|
||||
async execute(params: CompleteOnboardingInputDTO): Promise<Result<CompleteOnboardingViewData, string>> {
|
||||
try {
|
||||
const onboardingService = new OnboardingService();
|
||||
const result = await onboardingService.completeOnboarding(params);
|
||||
|
||||
if (result.isErr()) {
|
||||
const error = result.getError();
|
||||
return Result.err(error.message || 'Failed to complete onboarding');
|
||||
}
|
||||
|
||||
const output = CompleteOnboardingViewDataBuilder.build(result.unwrap());
|
||||
return Result.ok(output);
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : 'Failed to complete onboarding';
|
||||
return Result.err(errorMessage);
|
||||
const onboardingService = new OnboardingService();
|
||||
const result = await onboardingService.completeOnboarding(params);
|
||||
|
||||
if (result.isErr()) {
|
||||
return Result.err(mapToMutationError(result.getError()));
|
||||
}
|
||||
|
||||
const output = CompleteOnboardingViewDataBuilder.build(result.unwrap());
|
||||
return Result.ok(output);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Mutation } from '@/lib/contracts/mutations/Mutation';
|
||||
import { Result } from '@/lib/contracts/Result';
|
||||
import { mapToMutationError } from '@/lib/contracts/mutations/MutationError';
|
||||
import { OnboardingService } from '@/lib/services/onboarding/OnboardingService';
|
||||
import { RequestAvatarGenerationInputDTO } from '@/lib/types/generated/RequestAvatarGenerationInputDTO';
|
||||
import { GenerateAvatarsViewDataBuilder } from '@/lib/builders/view-data/GenerateAvatarsViewDataBuilder';
|
||||
@@ -11,7 +12,7 @@ export class GenerateAvatarsMutation implements Mutation<RequestAvatarGeneration
|
||||
const result = await service.generateAvatars(input);
|
||||
|
||||
if (result.isErr()) {
|
||||
return Result.err(result.getError().message);
|
||||
return Result.err(mapToMutationError(result.getError()));
|
||||
}
|
||||
|
||||
const output = GenerateAvatarsViewDataBuilder.build(result.unwrap());
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import { SponsorshipRequestsService } from '@/lib/services/sponsors/SponsorshipRequestsService';
|
||||
import type { AcceptSponsorshipRequestCommand } from '@/lib/services/sponsors/SponsorshipRequestsService';
|
||||
import type { Mutation } from '@/lib/contracts/mutations/Mutation';
|
||||
import { Result } from '@/lib/contracts/Result';
|
||||
import type { Result as ResultType } from '@/lib/contracts/Result';
|
||||
|
||||
export interface AcceptSponsorshipRequestCommand {
|
||||
requestId: string;
|
||||
actorDriverId: string;
|
||||
}
|
||||
|
||||
export type AcceptSponsorshipRequestMutationError =
|
||||
| 'ACCEPT_SPONSORSHIP_REQUEST_FAILED';
|
||||
@@ -18,7 +21,7 @@ export class AcceptSponsorshipRequestMutation
|
||||
|
||||
async execute(
|
||||
command: AcceptSponsorshipRequestCommand,
|
||||
): Promise<ResultType<void, AcceptSponsorshipRequestMutationError>> {
|
||||
): Promise<Result<void, AcceptSponsorshipRequestMutationError>> {
|
||||
const result = await this.service.acceptRequest(command);
|
||||
|
||||
if (result.isErr()) {
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import { SponsorshipRequestsService } from '@/lib/services/sponsors/SponsorshipRequestsService';
|
||||
import type { RejectSponsorshipRequestCommand } from '@/lib/services/sponsors/SponsorshipRequestsService';
|
||||
import type { Mutation } from '@/lib/contracts/mutations/Mutation';
|
||||
import { Result } from '@/lib/contracts/Result';
|
||||
import type { Result as ResultType } from '@/lib/contracts/Result';
|
||||
|
||||
export interface RejectSponsorshipRequestCommand {
|
||||
requestId: string;
|
||||
actorDriverId: string;
|
||||
reason: string | null;
|
||||
}
|
||||
|
||||
export type RejectSponsorshipRequestMutationError =
|
||||
| 'REJECT_SPONSORSHIP_REQUEST_FAILED';
|
||||
@@ -18,7 +22,7 @@ export class RejectSponsorshipRequestMutation
|
||||
|
||||
async execute(
|
||||
command: RejectSponsorshipRequestCommand,
|
||||
): Promise<ResultType<void, RejectSponsorshipRequestMutationError>> {
|
||||
): Promise<Result<void, RejectSponsorshipRequestMutationError>> {
|
||||
const result = await this.service.rejectRequest(command);
|
||||
|
||||
if (result.isErr()) {
|
||||
|
||||
Reference in New Issue
Block a user