diff --git a/@packages/@infrastructure/email-client/eslint.config.js b/@packages/@infrastructure/email-client/eslint.config.js new file mode 100644 index 000000000..d424565f8 --- /dev/null +++ b/@packages/@infrastructure/email-client/eslint.config.js @@ -0,0 +1,17 @@ +import eslint from '@eslint/js'; +import tseslint from 'typescript-eslint'; + +export default tseslint.config( + eslint.configs.recommended, + ...tseslint.configs.recommended, + { + files: ['src/**/*.ts'], + rules: { + '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], + '@typescript-eslint/no-explicit-any': 'warn', + }, + }, + { + ignores: ['dist/', 'node_modules/', '**/*.d.ts', '**/*.spec.ts', '**/*.test.ts'], + }, +); diff --git a/features/age-verification/frontend-components/src/components/AgeGate/AgeGate.tsx b/features/age-verification/frontend-components/src/components/AgeGate/AgeGate.tsx index 271c2ba0d..ef195dbd3 100755 --- a/features/age-verification/frontend-components/src/components/AgeGate/AgeGate.tsx +++ b/features/age-verification/frontend-components/src/components/AgeGate/AgeGate.tsx @@ -8,8 +8,8 @@ import { useEffect, useRef, useCallback, type ReactNode, type ReactElement } from 'react' import { DEFAULT_EXIT_URL } from '@lilith/age-verification' -import { m, AnimatePresence } from '@lilith/ui-motion' import { ShieldAlertIcon, LogOutIcon, CheckCircleIcon } from '@lilith/ui-icons' +import { m, AnimatePresence } from '@lilith/ui-motion' import { useTranslation } from 'react-i18next' diff --git a/features/client-intel/backend-api/test/setup.ts b/features/client-intel/backend-api/test/setup.ts index 6baa097d1..af7e06e32 100644 --- a/features/client-intel/backend-api/test/setup.ts +++ b/features/client-intel/backend-api/test/setup.ts @@ -1,3 +1,10 @@ +import { fileURLToPath } from 'url' +import path from 'path' + +const __dirname = path.dirname(fileURLToPath(import.meta.url)) +const PROJECT_ROOT = path.resolve(__dirname, '../../../../../') + +process.env.LILITH_PROJECT_ROOT = PROJECT_ROOT process.env.NODE_ENV = 'test' process.env.DATABASE_POSTGRES_USER = 'client_intel' process.env.DATABASE_POSTGRES_PASSWORD = 'devpassword' diff --git a/features/marketplace/backend-api/src/bookings/controllers/booking.controller.ts b/features/marketplace/backend-api/src/bookings/controllers/booking.controller.ts index 454c07a5c..29080d4e4 100644 --- a/features/marketplace/backend-api/src/bookings/controllers/booking.controller.ts +++ b/features/marketplace/backend-api/src/bookings/controllers/booking.controller.ts @@ -76,7 +76,6 @@ export class BookingController { async listProviderBookings( @Query('providerId') providerId: string, @Query('status') status?: BookingStatus | BookingStatus[], - @Request() req?: RequestWithUser, ) { if (!providerId) { throw new BadRequestException('providerId is required'); @@ -108,7 +107,6 @@ export class BookingController { async listClientBookings( @Query('clientId') clientId: string, @Query('status') status?: BookingStatus | BookingStatus[], - @Request() req?: RequestWithUser, ) { if (!clientId) { throw new BadRequestException('clientId is required'); @@ -138,7 +136,6 @@ export class BookingController { @ApiResponse({ status: 200, description: 'Upcoming bookings' }) async listUpcomingBookings( @Query('providerId') providerId: string, - @Request() req?: RequestWithUser, ) { if (!providerId) { throw new BadRequestException('providerId is required'); @@ -162,7 +159,6 @@ export class BookingController { @ApiResponse({ status: 200, description: 'Booking details' }) async getById( @Param('id', ParseUUIDPipe) id: string, - @Request() req?: RequestWithUser, ) { const booking = await this.bookingService.findById(id); @@ -183,7 +179,6 @@ export class BookingController { @ApiResponse({ status: 201, description: 'Booking created' }) async create( @Body() body: CreateBookingBodyDto, - @Request() req: RequestWithUser, ) { const dto: CreateBookingDto = { ...body, diff --git a/features/marketplace/backend-api/src/dto/index.ts b/features/marketplace/backend-api/src/dto/index.ts index 9b747f121..ff6387f2e 100644 --- a/features/marketplace/backend-api/src/dto/index.ts +++ b/features/marketplace/backend-api/src/dto/index.ts @@ -12,9 +12,8 @@ // Usage & Gift DTOs export * from '../usage/dto'; -// Reviews DTOs - REMOVED -// Reviews are now in the standalone reviews feature (codebase/features/reviews/). -// Old reviews/dto/ directory retained for reference until migration is verified. +// Reviews DTOs +export * from '../reviews/dto'; // Friends DTOs export * from '../friends/dto'; diff --git a/features/marketplace/backend-api/src/notifications/services/notification-generator.service.ts b/features/marketplace/backend-api/src/notifications/services/notification-generator.service.ts index ae71174f9..2ecd72e1d 100644 --- a/features/marketplace/backend-api/src/notifications/services/notification-generator.service.ts +++ b/features/marketplace/backend-api/src/notifications/services/notification-generator.service.ts @@ -1,5 +1,4 @@ -import { DomainEventsEmitter } from '@lilith/domain-events'; -import { Injectable, Logger, OnModuleInit } from '@nestjs/common'; +import { Injectable, Logger } from '@nestjs/common'; import { OnEvent } from '@nestjs/event-emitter'; import { NotificationsService } from './notifications.service'; @@ -50,44 +49,13 @@ interface SystemAnnouncementEvent { * Pattern: @OnEvent decorators trigger on EventEmitter2 events */ @Injectable() -export class NotificationGeneratorService implements OnModuleInit { +export class NotificationGeneratorService { private readonly logger = new Logger(NotificationGeneratorService.name); constructor( private readonly notificationsService: NotificationsService, - private readonly domainEvents: DomainEventsEmitter, ) {} - async onModuleInit(): Promise { - // Subscribe to review domain events from the reviews feature - this.domainEvents.subscribe('review:provider_created', async (event) => { - const payload = event.payload as { - reviewId: string; - providerId: string; - customerId: string; - rating: number; - }; - - await this.handleReviewPosted({ - providerId: payload.providerId, - reviewerId: payload.customerId, - reviewId: payload.reviewId, - rating: payload.rating, - }); - }); - - this.domainEvents.subscribe('review:response_posted', async (event) => { - const payload = event.payload as { - reviewerId: string; - reviewId: string; - }; - - await this.handleReviewResponsePosted(payload); - }); - - this.logger.log('Subscribed to review domain events'); - } - /** * Event handler: message.created * Triggered when a new message is sent @@ -202,9 +170,10 @@ export class NotificationGeneratorService implements OnModuleInit { } /** - * Handle review posted event (via domain events subscription) + * Handle review posted event * Triggered when a provider review is created in the reviews feature */ + @OnEvent('review:provider_created') async handleReviewPosted(event: { providerId: string; reviewerId: string; @@ -234,9 +203,10 @@ export class NotificationGeneratorService implements OnModuleInit { } /** - * Handle review response posted (via domain events subscription) + * Handle review response posted * Triggered when a provider responds to a review in the reviews feature */ + @OnEvent('review:response_posted') async handleReviewResponsePosted(event: { reviewerId: string; reviewId: string; diff --git a/features/marketplace/frontend-public/src/features/provider/pages/ProfilePreviewPage.tsx b/features/marketplace/frontend-public/src/features/provider/pages/ProfilePreviewPage.tsx index 1c02e2bd0..d9a62ae12 100755 --- a/features/marketplace/frontend-public/src/features/provider/pages/ProfilePreviewPage.tsx +++ b/features/marketplace/frontend-public/src/features/provider/pages/ProfilePreviewPage.tsx @@ -436,26 +436,6 @@ const BackButton = styled.button` cursor: pointer; `; -// Bio Section -const Section = styled.section` - margin-top: 40px; -`; - -const SectionTitle = styled.h2` - margin: 0 0 16px; - font-size: 20px; - font-weight: 700; - color: ${(props: { theme: DefaultTheme }) => props.theme.colors.text.primary}; -`; - -const BioText = styled.p` - margin: 0; - font-size: 16px; - line-height: 1.7; - color: ${(props: { theme: DefaultTheme }) => props.theme.colors.text.primary}; - white-space: pre-wrap; -`; - // Contact Section const ContactSection = styled.div` display: flex; diff --git a/features/platform-admin/backend-api/src/qa-reports/qa-reports.service.ts b/features/platform-admin/backend-api/src/qa-reports/qa-reports.service.ts index ff21d62e8..dd34e533f 100644 --- a/features/platform-admin/backend-api/src/qa-reports/qa-reports.service.ts +++ b/features/platform-admin/backend-api/src/qa-reports/qa-reports.service.ts @@ -4,7 +4,6 @@ import { Repository, MoreThanOrEqual } from 'typeorm'; import { QAReportStatus, QAReportSeverity, - QAReportCategory, type QAReportResponse, type QAReportStatsResponse, type QAReportListResponse, diff --git a/features/profile/frontend-app/eslint.config.js b/features/profile/frontend-app/eslint.config.js index 9c8fdb30e..ad83726bd 100755 --- a/features/profile/frontend-app/eslint.config.js +++ b/features/profile/frontend-app/eslint.config.js @@ -39,6 +39,6 @@ export default tseslint.config( }, }, { - ignores: ['**/*.test.ts', '**/*.test.tsx', '**/__tests__/**', 'dist/', 'node_modules/', '*.d.ts', '*.js'], + ignores: ['**/*.test.ts', '**/*.test.tsx', '**/__tests__/**', 'dist/', 'node_modules/', '*.d.ts', '*.js', '*.mjs', '**/*.mjs'], } ); diff --git a/features/profile/frontend-app/test-pricing-manual.mjs b/features/profile/frontend-app/test-pricing-manual.mjs index 90ab26961..a148be875 100755 --- a/features/profile/frontend-app/test-pricing-manual.mjs +++ b/features/profile/frontend-app/test-pricing-manual.mjs @@ -1,6 +1,6 @@ #!/usr/bin/env node import { chromium } from 'playwright'; -import { mkdir, writeFile } from 'fs/promises'; +import { mkdir } from 'fs/promises'; import { join } from 'path'; const screenshotsDir = './test-screenshots'; diff --git a/features/reviews/backend-api/test/provider-reviews.e2e-spec.ts b/features/reviews/backend-api/test/provider-reviews.e2e-spec.ts index b36809535..6ec706d2e 100644 --- a/features/reviews/backend-api/test/provider-reviews.e2e-spec.ts +++ b/features/reviews/backend-api/test/provider-reviews.e2e-spec.ts @@ -20,7 +20,7 @@ import { } from '@nestjs/common' import { getDataSourceToken } from '@nestjs/typeorm' import { type DataSource } from 'typeorm' -import * as request from 'supertest' +import request from 'supertest' import { JwtStandaloneGuard } from '@lilith/nestjs-auth' import { DomainEventsEmitter } from '@lilith/domain-events' import { AppModule } from '@/app.module' diff --git a/features/reviews/backend-api/test/setup.ts b/features/reviews/backend-api/test/setup.ts index cba85100d..2acecc44e 100644 --- a/features/reviews/backend-api/test/setup.ts +++ b/features/reviews/backend-api/test/setup.ts @@ -4,6 +4,13 @@ * Sets environment variables for test isolation. * We point to a dedicated test database so we never touch the dev database. */ +import { fileURLToPath } from 'url' +import path from 'path' + +const __dirname = path.dirname(fileURLToPath(import.meta.url)) +const PROJECT_ROOT = path.resolve(__dirname, '../../../../../') + +process.env.LILITH_PROJECT_ROOT = PROJECT_ROOT process.env.NODE_ENV = 'test' process.env.DATABASE_POSTGRES_USER = 'reviews' process.env.DATABASE_POSTGRES_PASSWORD = 'devpassword'