feat(listings): add user-facing scam/abuse report flow (GOO-19)
- Add ListingFlag model with FlagReason enum (SCAM, DUPLICATE, WRONG_INFO, ALREADY_SOLD, INAPPROPRIATE) - Add POST /listings/:id/report endpoint with rate limiting and duplicate prevention - Auto-flag listings with ≥3 reports to PENDING_REVIEW for moderator review - Add GET /admin/flagged-listings endpoint for admin moderation queue - Add "Báo cáo" button + modal on listing detail page (Vietnamese UI) - Add Prisma migration for listing_flags table with unique constraint per user/listing Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { Module, type OnModuleInit } from '@nestjs/common';
|
||||
import { CqrsModule } from '@nestjs/cqrs';
|
||||
import { makeCounterProvider } from '@willsoto/nestjs-prometheus';
|
||||
import { LoggerService } from '@modules/shared';
|
||||
import { LoggerService, TypesenseClientService } from '@modules/shared';
|
||||
import { SubscriptionsModule } from '@modules/subscriptions';
|
||||
import { CreateSavedSearchHandler } from './application/commands/create-saved-search/create-saved-search.handler';
|
||||
import { DeleteSavedSearchHandler } from './application/commands/delete-saved-search/delete-saved-search.handler';
|
||||
@@ -21,7 +21,6 @@ import { SavedSearchAlertHandler } from './infrastructure/event-handlers/saved-s
|
||||
import { ListingIndexerService } from './infrastructure/services/listing-indexer.service';
|
||||
import { PostgresSearchRepository } from './infrastructure/services/postgres-search.repository';
|
||||
import { ResilientSearchRepository, SEARCH_DEGRADATION_TOTAL } from './infrastructure/services/resilient-search.repository';
|
||||
import { TypesenseClientService } from './infrastructure/services/typesense-client.service';
|
||||
import { TypesenseSearchRepository } from './infrastructure/services/typesense-search.repository';
|
||||
import { SavedSearchController } from './presentation/controllers/saved-search.controller';
|
||||
import { SearchController } from './presentation/controllers/search.controller';
|
||||
@@ -34,7 +33,6 @@ const QueryHandlers = [SearchPropertiesHandler, GeoSearchHandler, GetSavedSearch
|
||||
controllers: [SearchController, SavedSearchController],
|
||||
providers: [
|
||||
// Infrastructure
|
||||
TypesenseClientService,
|
||||
TypesenseSearchRepository,
|
||||
PostgresSearchRepository,
|
||||
ResilientSearchRepository,
|
||||
@@ -61,11 +59,10 @@ const QueryHandlers = [SearchPropertiesHandler, GeoSearchHandler, GetSavedSearch
|
||||
...CommandHandlers,
|
||||
...QueryHandlers,
|
||||
],
|
||||
exports: [ListingIndexerService, SEARCH_REPOSITORY, TypesenseClientService],
|
||||
exports: [ListingIndexerService, SEARCH_REPOSITORY],
|
||||
})
|
||||
export class SearchModule implements OnModuleInit {
|
||||
constructor(
|
||||
private readonly typesenseClient: TypesenseClientService,
|
||||
private readonly searchRepo: ResilientSearchRepository,
|
||||
private readonly logger: LoggerService,
|
||||
) {}
|
||||
|
||||
Reference in New Issue
Block a user