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:
Ho Ngoc Hai
2026-04-23 00:19:12 +07:00
parent 94d462ef4f
commit 0329455e9a
26 changed files with 615 additions and 57 deletions

View File

@@ -19,6 +19,7 @@ import { RequestLoggingMiddleware } from './infrastructure/middleware/request-lo
import { SanitizeInputMiddleware } from './infrastructure/middleware/sanitize-input.middleware';
import { PrismaService } from './infrastructure/prisma.service';
import { RedisService } from './infrastructure/redis.service';
import { TypesenseClientService } from './infrastructure/typesense-client.service';
@Global()
@Module({
@@ -34,6 +35,7 @@ import { RedisService } from './infrastructure/redis.service';
RedisService,
CacheService,
EventBusService,
TypesenseClientService,
makeCounterProvider({
name: CACHE_HIT_TOTAL,
help: 'Total number of cache hits',
@@ -54,7 +56,7 @@ import { RedisService } from './infrastructure/redis.service';
useClass: GlobalExceptionFilter,
},
],
exports: [PrismaService, RedisService, CacheService, LoggerService, EventBusService, FieldEncryptionService, PrometheusModule],
exports: [PrismaService, RedisService, CacheService, LoggerService, EventBusService, FieldEncryptionService, TypesenseClientService, PrometheusModule],
})
export class SharedModule implements NestModule {
configure(consumer: MiddlewareConsumer): void {