From 2d83d235421c3b9c1c7f7155e04799109eaf56d2 Mon Sep 17 00:00:00 2001 From: CapoMK25 Date: Fri, 12 Jun 2026 17:58:52 +0300 Subject: [PATCH 1/2] feat(flea-market): add IN_STOCK status and deprecate GET /fleaMarket --- src/fleaMarket/enum/status.enum.ts | 1 + src/fleaMarket/fleaMarket.controller.ts | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/fleaMarket/enum/status.enum.ts b/src/fleaMarket/enum/status.enum.ts index 15635ea7e..1ff64b309 100644 --- a/src/fleaMarket/enum/status.enum.ts +++ b/src/fleaMarket/enum/status.enum.ts @@ -7,4 +7,5 @@ export enum Status { AVAILABLE = 'available', SHIPPING = 'shipping', BOOKED = 'booked', + IN_STOCK = 'in_stock', } diff --git a/src/fleaMarket/fleaMarket.controller.ts b/src/fleaMarket/fleaMarket.controller.ts index 8a02d426e..e331209ed 100644 --- a/src/fleaMarket/fleaMarket.controller.ts +++ b/src/fleaMarket/fleaMarket.controller.ts @@ -29,7 +29,7 @@ export class FleaMarketController { private readonly service: FleaMarketService, private readonly playerService: PlayerService, private readonly emitterService: EventEmitterService, - ) {} + ) { } /** * Fetch all the furniture, that the clan has accepted for selling @@ -85,6 +85,10 @@ export class FleaMarketController { * Get all flea market items * * @remarks Get all FleaMarketItems of the flea market + * @deprecated This endpoint is deprecated because it returns all flea market items from + * every clan globally, leading to data leaks and scaling bottlenecks. To view a clan's + * complete furniture view, use the Stock endpoint (GET /stock/:id) which safely handles + * both regular stock and active flea market items for that specific clan. */ @ApiResponseDescription({ success: { From bc13aca9a028f2bf11424f54d977abb3d2f54973 Mon Sep 17 00:00:00 2001 From: CapoMK25 Date: Thu, 18 Jun 2026 20:18:01 +0300 Subject: [PATCH 2/2] catastrophically failing setup --- src/clan/clan.module.ts | 8 +++---- src/clan/clan.service.ts | 5 ++++- src/clan/utils/clanHelper.service.ts | 3 ++- src/clanInventory/clanInventory.module.ts | 9 +++++--- src/clanInventory/stock/dto/stock.dto.ts | 8 +++++++ src/clanInventory/stock/stock.controller.ts | 8 +++---- src/clanInventory/stock/stock.service.ts | 25 +++++++++++++++++---- src/fleaMarket/fleaMarket.controller.ts | 2 +- src/fleaMarket/fleaMarket.module.ts | 8 +++---- src/fleaMarket/fleaMarket.service.ts | 3 ++- 10 files changed, 56 insertions(+), 23 deletions(-) diff --git a/src/clan/clan.module.ts b/src/clan/clan.module.ts index c8ac84069..1d3e66056 100644 --- a/src/clan/clan.module.ts +++ b/src/clan/clan.module.ts @@ -1,4 +1,4 @@ -import { Module } from '@nestjs/common'; +import { Module, forwardRef } from '@nestjs/common'; import { MongooseModule } from '@nestjs/mongoose'; import { ClanSchema } from './clan.schema'; import { ClanController } from './clan.controller'; @@ -27,11 +27,11 @@ import { EventEmitterCommonModule } from '../common/service/EventEmitterService/ { name: ModelName.CLAN, schema: ClanSchema }, { name: ModelName.PLAYER, schema: PlayerSchema }, ]), - ClanInventoryModule, + forwardRef(() => ClanInventoryModule), RequestHelperModule, PlayerModule, GameEventsEmitterModule, - VotingModule, + forwardRef(() => VotingModule), ChatModule, EventEmitterCommonModule, ], @@ -53,4 +53,4 @@ import { EventEmitterCommonModule } from '../common/service/EventEmitterService/ PasswordGenerator, ], }) -export class ClanModule {} +export class ClanModule {} \ No newline at end of file diff --git a/src/clan/clan.service.ts b/src/clan/clan.service.ts index b734ff82d..6b83aa783 100644 --- a/src/clan/clan.service.ts +++ b/src/clan/clan.service.ts @@ -52,7 +52,10 @@ export class ClanService { @InjectConnection() private readonly connection: Connection, @Inject(PasswordGenerator) private readonly passwordGenerator: PasswordGenerator, + + @Inject(forwardRef(() => StockService)) // <-- MAOC FIX APPLIED HERE private readonly stockService: StockService, + private readonly soulhomeService: SoulHomeService, private readonly clanHelperService: ClanHelperService, private readonly emitter: GameEventEmitter, @@ -364,4 +367,4 @@ export class ClanService { return await endTransaction(session, true); } -} +} \ No newline at end of file diff --git a/src/clan/utils/clanHelper.service.ts b/src/clan/utils/clanHelper.service.ts index 0f48d0ef3..d71e82aa4 100644 --- a/src/clan/utils/clanHelper.service.ts +++ b/src/clan/utils/clanHelper.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@nestjs/common'; +import { Injectable, Inject, forwardRef } from '@nestjs/common'; import { getStockDefaultItems, getRoomDefaultItems, @@ -19,6 +19,7 @@ import { ClientSession } from 'mongoose'; @Injectable() export default class ClanHelperService { constructor( + @Inject(forwardRef(() => StockService)) private readonly stockService: StockService, private readonly soulHomeService: SoulHomeService, private readonly roomService: RoomService, diff --git a/src/clanInventory/clanInventory.module.ts b/src/clanInventory/clanInventory.module.ts index daa2f5533..ee521ee2e 100644 --- a/src/clanInventory/clanInventory.module.ts +++ b/src/clanInventory/clanInventory.module.ts @@ -1,4 +1,4 @@ -import { Module } from '@nestjs/common'; +import { Module, forwardRef } from '@nestjs/common'; import { MongooseModule } from '@nestjs/mongoose'; import { ModelName } from '../common/enum/modelName.enum'; import { PlayerSchema } from '../player/schemas/player.schema'; @@ -23,7 +23,8 @@ import { StockSchema } from './stock/stock.schema'; import { StockService } from './stock/stock.service'; import { ClanSchema } from '../clan/clan.schema'; import { StealTokenGuard } from './item/guards/StealToken.guard'; -import { AuthorizationModule } from '../authorization/authorization.module'; +import { AuthorizationModule } from '../authorization/authorization.module' +import { FleaMarketModule } from '../fleaMarket/fleaMarket.module'; @Module({ imports: [ @@ -39,6 +40,8 @@ import { AuthorizationModule } from '../authorization/authorization.module'; RequestHelperModule, AuthModule, AuthorizationModule, + + forwardRef(() => FleaMarketModule), ], controllers: [ StockController, @@ -67,4 +70,4 @@ import { AuthorizationModule } from '../authorization/authorization.module'; SoulHomeService, ], }) -export class ClanInventoryModule {} +export class ClanInventoryModule {} \ No newline at end of file diff --git a/src/clanInventory/stock/dto/stock.dto.ts b/src/clanInventory/stock/dto/stock.dto.ts index 8b9e47b55..523a5aaac 100644 --- a/src/clanInventory/stock/dto/stock.dto.ts +++ b/src/clanInventory/stock/dto/stock.dto.ts @@ -3,6 +3,7 @@ import { ItemDto } from '../../item/dto/item.dto'; import { ClanDto } from '../../../clan/dto/clan.dto'; import AddType from '../../../common/base/decorator/AddType.decorator'; import { ExtractField } from '../../../common/decorator/response/ExtractField'; +import { FleaMarketItemDto } from '../../../fleaMarket/dto/fleaMarketItem.dto'; @AddType('StockDto') export class StockDto { @@ -45,4 +46,11 @@ export class StockDto { @Type(() => ItemDto) @Expose() Item: ItemDto[]; + + /** + * FleaMarketItems associated with this stock's clan + */ + @Type(() => FleaMarketItemDto) + @Expose() + FleaMarketItem: FleaMarketItemDto[]; } diff --git a/src/clanInventory/stock/stock.controller.ts b/src/clanInventory/stock/stock.controller.ts index 281e7f2c4..bce62b001 100644 --- a/src/clanInventory/stock/stock.controller.ts +++ b/src/clanInventory/stock/stock.controller.ts @@ -21,10 +21,10 @@ export class StockController { /** * Get stock by _id - * - * @remarks Read Stock data by its _id field. - * - * Notice that everybody is able to read any Stock data. + * @remarks Returns the Stock document with the given _id. Includes both the + * clan's active stock items (under `Item`) and FleaMarketItems currently in the + * sell lifecycle (under `FleaMarketItem`). Consolidates the complete view of + * clan furniture into a single decoupled request. */ @ApiResponseDescription({ success: { diff --git a/src/clanInventory/stock/stock.service.ts b/src/clanInventory/stock/stock.service.ts index 57643138c..42926ba0a 100644 --- a/src/clanInventory/stock/stock.service.ts +++ b/src/clanInventory/stock/stock.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@nestjs/common'; +import { Injectable, forwardRef, Inject } from '@nestjs/common'; import { Model, ClientSession } from 'mongoose'; import { InjectModel } from '@nestjs/mongoose'; import { Stock } from './stock.schema'; @@ -8,6 +8,7 @@ import { StockDto } from './dto/stock.dto'; import { ItemService } from '../item/item.service'; import { ModelName } from '../../common/enum/modelName.enum'; import BasicService from '../../common/service/basicService/BasicService'; +import { FleaMarketService } from '../../fleaMarket/fleaMarket.service'; import { TReadByIdOptions, TIServiceReadManyOptions, @@ -21,6 +22,8 @@ export class StockService { public constructor( @InjectModel(Stock.name) public readonly model: Model, private readonly itemService: ItemService, + @Inject(forwardRef(() => FleaMarketService)) + private readonly fleaMarketService: FleaMarketService, ) { this.refsInModel = [ModelName.CLAN, ModelName.ITEM]; this.modelName = ModelName.STOCK; @@ -58,7 +61,21 @@ export class StockService { optionsToApply.includeRefs = options.includeRefs.filter((ref) => this.refsInModel.includes(ref), ); - return this.basicService.readOneById(_id, optionsToApply); + + const [stock, errors] = await this.basicService.readOneById( + _id, + optionsToApply, + ); + if (errors) return [null, errors]; + + const [fleaMarketItems] = await this.fleaMarketService.basicService.readMany({ + filter: { clan_id: stock.clan_id }, + }); + + return [ + { ...stock, FleaMarketItem: fleaMarketItems ?? [] }, + null, + ]; } /** @@ -90,7 +107,7 @@ export class StockService { cellCountChange: number, ): Promise<[boolean | null, ServiceError[] | null]> => { const [stock, errors] = await this.basicService.readOneById(_id); - if (errors || !stock) return [null, errors]; + if (errors) return [null, errors]; const { cellCount } = stock; @@ -125,4 +142,4 @@ export class StockService { await this.itemService.deleteAllStockItems(_id, options); return this.basicService.deleteOneById(_id, options); } -} +} \ No newline at end of file diff --git a/src/fleaMarket/fleaMarket.controller.ts b/src/fleaMarket/fleaMarket.controller.ts index a3e389549..1c9d91235 100644 --- a/src/fleaMarket/fleaMarket.controller.ts +++ b/src/fleaMarket/fleaMarket.controller.ts @@ -29,7 +29,7 @@ export class FleaMarketController { private readonly service: FleaMarketService, private readonly playerService: PlayerService, private readonly emitterService: EventEmitterService, - ) { } + ) {} /** * Fetch all the furniture, that the clan has accepted for selling diff --git a/src/fleaMarket/fleaMarket.module.ts b/src/fleaMarket/fleaMarket.module.ts index 034908ea0..2faf14da4 100644 --- a/src/fleaMarket/fleaMarket.module.ts +++ b/src/fleaMarket/fleaMarket.module.ts @@ -1,4 +1,4 @@ -import { Module } from '@nestjs/common'; +import { Module, forwardRef } from '@nestjs/common'; import { MongooseModule } from '@nestjs/mongoose'; import { ModelName } from '../common/enum/modelName.enum'; import { FleaMarketItemSchema } from './fleaMarketItem.schema'; @@ -26,10 +26,10 @@ import { EventEmitterCommonModule } from '../common/service/EventEmitterService/ { name: ModelName.PLAYER, schema: PlayerSchema }, { name: ModelName.CLAN, schema: ClanSchema }, ]), - ClanInventoryModule, + forwardRef(() => ClanInventoryModule), PlayerModule, VotingModule, - ClanModule, + forwardRef(() => ClanModule), RequestHelperModule, EventEmitterCommonModule, ], @@ -40,6 +40,6 @@ import { EventEmitterCommonModule } from '../common/service/EventEmitterService/ FleaMarketVotingProcessor, StallService, ], - exports: [], + exports: [FleaMarketService], }) export class FleaMarketModule {} diff --git a/src/fleaMarket/fleaMarket.service.ts b/src/fleaMarket/fleaMarket.service.ts index b60833987..588862de3 100644 --- a/src/fleaMarket/fleaMarket.service.ts +++ b/src/fleaMarket/fleaMarket.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@nestjs/common'; +import { Injectable, Inject, forwardRef } from '@nestjs/common'; import { OnEvent } from '@nestjs/event-emitter'; import { InjectConnection, InjectModel } from '@nestjs/mongoose'; import { FleaMarketItem, publicReferences } from './fleaMarketItem.schema'; @@ -50,6 +50,7 @@ export class FleaMarketService { private readonly itemService: ItemService, private readonly votingService: VotingService, private readonly votingQueue: VotingQueue, + @Inject(forwardRef(() => ClanService)) private readonly clanService: ClanService, @InjectConnection() private readonly connection: Connection, ) {