website refactor
This commit is contained in:
@@ -108,6 +108,7 @@ export class AuthService {
|
||||
userId: coreSession.user.id,
|
||||
email: coreSession.user.email ?? '',
|
||||
displayName: coreSession.user.displayName,
|
||||
...(coreSession.user.primaryDriverId ? { primaryDriverId: coreSession.user.primaryDriverId } : {}),
|
||||
...(role !== undefined ? { role } : {}),
|
||||
},
|
||||
};
|
||||
@@ -138,6 +139,7 @@ export class AuthService {
|
||||
id: userDTO.userId,
|
||||
displayName: userDTO.displayName,
|
||||
email: userDTO.email,
|
||||
...(userDTO.primaryDriverId ? { primaryDriverId: userDTO.primaryDriverId } : {}),
|
||||
...(inferredRole ? { role: inferredRole } : {}),
|
||||
});
|
||||
|
||||
@@ -173,6 +175,7 @@ export class AuthService {
|
||||
id: userDTO.userId,
|
||||
displayName: userDTO.displayName,
|
||||
email: userDTO.email,
|
||||
...(userDTO.primaryDriverId ? { primaryDriverId: userDTO.primaryDriverId } : {}),
|
||||
...(inferredRole ? { role: inferredRole } : {}),
|
||||
});
|
||||
|
||||
@@ -212,6 +215,7 @@ export class AuthService {
|
||||
id: userDTO.userId,
|
||||
displayName: userDTO.displayName,
|
||||
email: userDTO.email,
|
||||
...(userDTO.primaryDriverId ? { primaryDriverId: userDTO.primaryDriverId } : {}),
|
||||
...(inferredRole ? { role: inferredRole } : {}),
|
||||
},
|
||||
sessionOptions
|
||||
|
||||
@@ -3,7 +3,7 @@ import { CanActivate, ExecutionContext, Inject, Injectable } from '@nestjs/commo
|
||||
import { IDENTITY_SESSION_PORT_TOKEN } from './AuthProviders';
|
||||
|
||||
type AuthenticatedRequest = {
|
||||
user?: { userId: string; role?: string | undefined };
|
||||
user?: { userId: string; role?: string | undefined; primaryDriverId?: string | undefined };
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
@@ -22,9 +22,11 @@ export class AuthenticationGuard implements CanActivate {
|
||||
|
||||
const session = await this.sessionPort.getCurrentSession();
|
||||
if (session?.user?.id) {
|
||||
console.log(`[AuthenticationGuard] Session found for user: ${session.user.id}, primaryDriverId: ${session.user.primaryDriverId}`);
|
||||
request.user = {
|
||||
userId: session.user.id,
|
||||
role: session.user.role
|
||||
role: session.user.role,
|
||||
primaryDriverId: session.user.primaryDriverId
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ describe('DashboardController', () => {
|
||||
};
|
||||
mockService.getDashboardOverview.mockResolvedValue(overview);
|
||||
|
||||
const result = await controller.getDashboardOverview(driverId, { user: { userId: driverId } });
|
||||
const result = await controller.getDashboardOverview(driverId, { user: { userId: driverId, primaryDriverId: driverId } });
|
||||
|
||||
expect(mockService.getDashboardOverview).toHaveBeenCalledWith(driverId);
|
||||
expect(result).toEqual(overview);
|
||||
@@ -55,7 +55,7 @@ describe('DashboardController', () => {
|
||||
describe('auth guards (HTTP)', () => {
|
||||
let app: import("@nestjs/common").INestApplication;
|
||||
|
||||
const sessionPort: { getCurrentSession: () => Promise<null | { token: string; user: { id: string } }> } = {
|
||||
const sessionPort: { getCurrentSession: () => Promise<null | { token: string; user: { id: string; primaryDriverId?: string } }> } = {
|
||||
getCurrentSession: vi.fn(async () => null),
|
||||
};
|
||||
|
||||
@@ -128,7 +128,7 @@ describe('DashboardController', () => {
|
||||
it('allows endpoint when authenticated via session port', async () => {
|
||||
vi.mocked(sessionPort.getCurrentSession).mockResolvedValueOnce({
|
||||
token: 't',
|
||||
user: { id: 'user-1' },
|
||||
user: { id: 'user-1', primaryDriverId: 'driver-1' },
|
||||
});
|
||||
|
||||
await request(app.getHttpServer()).get('/dashboard/overview?driverId=d1').expect(200);
|
||||
|
||||
@@ -4,7 +4,7 @@ import { DashboardService } from './DashboardService';
|
||||
import { DashboardOverviewDTO } from './dtos/DashboardOverviewDTO';
|
||||
|
||||
type AuthenticatedRequest = {
|
||||
user?: { userId: string };
|
||||
user?: { userId: string; primaryDriverId?: string };
|
||||
};
|
||||
|
||||
@ApiTags('dashboard')
|
||||
@@ -21,10 +21,10 @@ export class DashboardController {
|
||||
@Query('driverId') _driverId: string,
|
||||
@Req() req: AuthenticatedRequest,
|
||||
): Promise<DashboardOverviewDTO> {
|
||||
const userId = req.user?.userId;
|
||||
if (!userId) {
|
||||
throw new UnauthorizedException('Unauthorized');
|
||||
const driverId = req.user?.primaryDriverId;
|
||||
if (!driverId) {
|
||||
throw new UnauthorizedException('Unauthorized: No driver associated with user');
|
||||
}
|
||||
return this.dashboardService.getDashboardOverview(userId);
|
||||
return this.dashboardService.getDashboardOverview(driverId);
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ import { GetDriverOutputDTO } from './dtos/GetDriverOutputDTO';
|
||||
import { GetDriverProfileOutputDTO } from './dtos/GetDriverProfileOutputDTO';
|
||||
|
||||
interface AuthenticatedRequest extends Request {
|
||||
user?: { userId: string };
|
||||
user?: { userId: string; primaryDriverId?: string };
|
||||
}
|
||||
|
||||
describe('DriverController', () => {
|
||||
@@ -82,13 +82,13 @@ describe('DriverController', () => {
|
||||
it('should return current driver if userId exists', async () => {
|
||||
const userId = 'user-123';
|
||||
const driver: GetDriverOutputDTO = { id: 'driver-123', name: 'Driver' } as GetDriverOutputDTO;
|
||||
service.getCurrentDriver.mockResolvedValue(driver);
|
||||
service.getDriver.mockResolvedValue(driver);
|
||||
|
||||
const mockReq: Partial<AuthenticatedRequest> = { user: { userId } };
|
||||
const mockReq: Partial<AuthenticatedRequest> = { user: { userId, primaryDriverId: userId } };
|
||||
|
||||
const result = await controller.getCurrentDriver(mockReq as AuthenticatedRequest);
|
||||
|
||||
expect(service.getCurrentDriver).toHaveBeenCalledWith(userId);
|
||||
expect(service.getDriver).toHaveBeenCalledWith(userId);
|
||||
expect(result).toEqual(driver);
|
||||
});
|
||||
|
||||
@@ -188,7 +188,7 @@ describe('DriverController', () => {
|
||||
describe('auth guards (HTTP)', () => {
|
||||
let app: import("@nestjs/common").INestApplication;
|
||||
|
||||
const sessionPort: { getCurrentSession: () => Promise<null | { token: string; user: { id: string } }> } = {
|
||||
const sessionPort: { getCurrentSession: () => Promise<null | { token: string; user: { id: string; primaryDriverId?: string } }> } = {
|
||||
getCurrentSession: vi.fn(async () => null),
|
||||
};
|
||||
|
||||
@@ -215,7 +215,7 @@ describe('DriverController', () => {
|
||||
provide: DriverService,
|
||||
useValue: {
|
||||
getDriversLeaderboard: vi.fn(async () => ({ drivers: [], totalRaces: 0, totalWins: 0, activeCount: 0 })),
|
||||
getCurrentDriver: vi.fn(async () => ({ id: 'd1' })),
|
||||
getDriver: vi.fn(async () => ({ id: 'd1' })),
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -249,7 +249,7 @@ describe('DriverController', () => {
|
||||
it('allows non-public endpoint when authenticated via session port', async () => {
|
||||
vi.mocked(sessionPort.getCurrentSession).mockResolvedValueOnce({
|
||||
token: 't',
|
||||
user: { id: 'user-1' },
|
||||
user: { id: 'user-1', primaryDriverId: 'driver-1' },
|
||||
});
|
||||
|
||||
await request(app.getHttpServer()).get('/drivers/current').expect(200);
|
||||
|
||||
@@ -13,7 +13,7 @@ import { GetDriverOutputDTO } from './dtos/GetDriverOutputDTO';
|
||||
import { GetDriverProfileOutputDTO } from './dtos/GetDriverProfileOutputDTO';
|
||||
|
||||
type AuthenticatedRequest = {
|
||||
user?: { userId: string };
|
||||
user?: { userId: string; primaryDriverId?: string };
|
||||
};
|
||||
|
||||
|
||||
@@ -43,12 +43,12 @@ export class DriverController {
|
||||
@ApiResponse({ status: 200, description: 'Current driver data', type: GetDriverOutputDTO })
|
||||
@ApiResponse({ status: 404, description: 'Driver not found' })
|
||||
async getCurrentDriver(@Req() req: AuthenticatedRequest): Promise<GetDriverOutputDTO | null> {
|
||||
const userId = req.user?.userId;
|
||||
if (!userId) {
|
||||
const driverId = req.user?.primaryDriverId;
|
||||
if (!driverId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return await this.driverService.getCurrentDriver(userId);
|
||||
return await this.driverService.getDriver(driverId);
|
||||
}
|
||||
|
||||
@Post('complete-onboarding')
|
||||
|
||||
@@ -19,10 +19,10 @@ describe('DriverService', () => {
|
||||
// Mocks for presenters
|
||||
const driversLeaderboardPresenter = { present: vi.fn(), getResponseModel: vi.fn() };
|
||||
const driverStatsPresenter = { present: vi.fn(), getResponseModel: vi.fn() };
|
||||
const completeOnboardingPresenter = { getResponseModel: vi.fn() };
|
||||
const driverRegistrationStatusPresenter = { getResponseModel: vi.fn() };
|
||||
const completeOnboardingPresenter = { present: vi.fn(), getResponseModel: vi.fn() };
|
||||
const driverRegistrationStatusPresenter = { present: vi.fn(), getResponseModel: vi.fn() };
|
||||
const driverPresenter = { present: vi.fn(), getResponseModel: vi.fn() };
|
||||
const driverProfilePresenter = { getResponseModel: vi.fn() };
|
||||
const driverProfilePresenter = { present: vi.fn(), getResponseModel: vi.fn() };
|
||||
const getDriverLiveriesPresenter = { present: vi.fn(), getResponseModel: vi.fn() };
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -116,6 +116,7 @@ export class DriverService {
|
||||
if (result.isErr()) {
|
||||
throw new Error(result.unwrapErr().details.message);
|
||||
}
|
||||
await this.completeOnboardingPresenter!.present(result.unwrap());
|
||||
return this.completeOnboardingPresenter!.getResponseModel();
|
||||
}
|
||||
|
||||
@@ -132,6 +133,7 @@ export class DriverService {
|
||||
if (result.isErr()) {
|
||||
throw new Error(result.unwrapErr().details.message);
|
||||
}
|
||||
await this.driverRegistrationStatusPresenter!.present(result.unwrap());
|
||||
return this.driverRegistrationStatusPresenter!.getResponseModel();
|
||||
}
|
||||
|
||||
@@ -190,6 +192,7 @@ export class DriverService {
|
||||
if (result.isErr()) {
|
||||
throw new Error(result.unwrapErr().details.message);
|
||||
}
|
||||
await this.driverProfilePresenter!.present(result.unwrap());
|
||||
return this.driverProfilePresenter!.getResponseModel();
|
||||
}
|
||||
|
||||
|
||||
@@ -78,9 +78,10 @@ async function bootstrap() {
|
||||
|
||||
// Start server
|
||||
try {
|
||||
await app.listen(3000);
|
||||
console.log('✅ API Server started successfully on port 3000');
|
||||
console.log('📚 Swagger docs: http://localhost:3000/api/docs');
|
||||
const port = process.env.PORT || 3000;
|
||||
await app.listen(port);
|
||||
console.log(`✅ API Server started successfully on port ${port}`);
|
||||
console.log(`📚 Swagger docs: http://localhost:${port}/api/docs`);
|
||||
} catch (error: unknown) {
|
||||
console.error('❌ Failed to start API server:', error instanceof Error ? error.message : 'Unknown error');
|
||||
process.exit(1);
|
||||
|
||||
Reference in New Issue
Block a user