Fix SMS, and added pagination+sorting+searching for GETs

This commit is contained in:
SepehrYahyaee
2026-05-20 14:57:10 +03:30
parent e4dfe7c572
commit 44723259d6
18 changed files with 519 additions and 30 deletions

View File

@@ -1,3 +1,4 @@
import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
import { RequestManagementModel } from "src/request-management/entities/schema/request-management.schema";
export class AllRequestDto {
@@ -122,7 +123,30 @@ export class AllRequestDtoV2 {
export class AllRequestDtoRsV2 {
data: AllRequestDtoV2[];
constructor(items: AllRequestDtoV2[]) {
this.data = items;
@ApiProperty({ description: "Total rows after search filter" })
total: number;
@ApiPropertyOptional()
page?: number;
@ApiPropertyOptional()
limit?: number;
@ApiPropertyOptional()
totalPages?: number;
constructor(payload: {
data: AllRequestDtoV2[];
total: number;
page?: number;
limit?: number;
totalPages?: number;
}) {
this.data = payload.data;
this.total = payload.total;
this.page = payload.page;
this.limit = payload.limit;
this.totalPages = payload.totalPages;
}
}

View File

@@ -21,6 +21,8 @@ import {
expertPortfolioFileIdsFromActivityEvents,
objectIdsFromStringSet,
} from "src/helpers/expert-portfolio";
import { applyListQueryV2 } from "src/helpers/list-query-v2";
import { ListQueryV2Dto } from "src/common/dto/list-query-v2.dto";
import { RequestManagementDbService } from "src/request-management/entities/db-service/request-management.db.service";
import { BlameRequestDbService } from "src/request-management/entities/db-service/blame-request.db.service";
import {
@@ -275,7 +277,10 @@ export class ExpertBlameService {
return buckets;
}
async findAllV2(actor: any): Promise<AllRequestDtoRsV2> {
async findAllV2(
actor: any,
query: ListQueryV2Dto = {},
): Promise<AllRequestDtoRsV2> {
try {
requireActorClientKey(actor);
const expertId = actor.sub;
@@ -354,10 +359,41 @@ export class ExpertBlameService {
}
}
const items: AllRequestDtoV2[] = visibleCases.map(
(doc) => this.mapBlameRequestToListItemV2(doc),
const paged = applyListQueryV2(visibleCases, {
publicId: (doc) => String((doc as { publicId?: string }).publicId ?? ""),
createdAt: (doc) => (doc as { createdAt?: Date }).createdAt,
requestNo: (doc) =>
String(
(doc as { requestNo?: string }).requestNo ??
(doc as { publicId?: string }).publicId ??
"",
),
status: (doc) => String((doc as { status?: string }).status ?? ""),
searchExtras: (doc) => {
const d = doc as {
_id?: unknown;
blameStatus?: string;
type?: string;
};
return [
String(d._id ?? ""),
d.blameStatus,
d.type,
].filter(Boolean) as string[];
},
}, query);
const items: AllRequestDtoV2[] = paged.list.map((doc) =>
this.mapBlameRequestToListItemV2(doc),
);
return new AllRequestDtoRsV2(items);
return new AllRequestDtoRsV2({
data: items,
total: paged.total,
page: paged.page,
limit: paged.limit,
totalPages: paged.totalPages,
});
} catch (error) {
if (error instanceof HttpException) throw error;
this.logger.error("findAllV2 failed", error instanceof Error ? error.stack : String(error));

View File

@@ -6,6 +6,7 @@ import {
InternalServerErrorException,
Param,
Put,
Query,
UseGuards,
} from "@nestjs/common";
import { ApiBearerAuth, ApiBody, ApiOperation, ApiParam, ApiTags } from "@nestjs/swagger";
@@ -15,6 +16,8 @@ import { Roles } from "src/decorators/roles.decorator";
import { CurrentUser } from "src/decorators/user.decorator";
import { RoleEnum } from "src/Types&Enums/role.enum";
import { ExpertBlameService } from "./expert-blame.service";
import { ListQueryV2Dto } from "src/common/dto/list-query-v2.dto";
import { AllRequestDtoRsV2 } from "./dto/all-request.dto";
import { SubmitReplyDto } from "./dto/reply.dto";
import { ResendRequestDto } from "./dto/resend.dto";
@@ -27,9 +30,17 @@ export class ExpertBlameV2Controller {
constructor(private readonly expertBlameService: ExpertBlameService) { }
@Get()
async findAll(@CurrentUser() actor: any) {
@ApiOperation({
summary: "List blame cases for field expert (V2)",
description:
"Optional query: `search`, `sortBy` (publicId | createdAt | requestNo | status), `sortOrder`, `page`, `limit`. Without `page`/`limit`, returns the full filtered list.",
})
async findAll(
@CurrentUser() actor: any,
@Query() query: ListQueryV2Dto,
): Promise<AllRequestDtoRsV2> {
try {
return await this.expertBlameService.findAllV2(actor);
return await this.expertBlameService.findAllV2(actor, query);
} catch (error) {
if (error instanceof HttpException) throw error;
throw new InternalServerErrorException(