All files / src/modules/listings listing.resolver.ts

78.43% Statements 40/51
69.23% Branches 36/52
68% Functions 17/25
77.55% Lines 38/49

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 9511x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x   22x 11x 11x   22x 11x 11x             22x 11x 11x           22x     11x             22x     11x 11x           22x     11x 11x             22x     11x 11x           22x     11x 11x           22x     11x 11x          
import { Resolver, Query, Args, Int, Mutation } from '@nestjs/graphql';
import { Listing } from '@app/modules/listings/listing.model';
import { ListingsService } from '@app/modules/listings/listings.service';
import { ListingsFilterDto } from '@app/modules/listings/dto/listings-filter.dto';
import { sanitizeInput } from '@app/utils/sanitize';
import { CreateListingInput } from '@app/modules/listings/dto/create-listing.input';
import { UpdateListingInput } from '@app/modules/listings/dto/update-listing.input';
import { UseGuards } from '@nestjs/common';
import { GqlAuthGuard } from '@app/common/guards/gql-auth.guard';
import { RolesGuard } from '@app/common/guards/roles.guard';
import { Roles } from '@app/common/decorators/roles.decorator';
import { CurrentUser } from '@app/common/decorators/current-user.decorator';
 
@Resolver(() => Listing)
export class ListingResolver {
  constructor(private readonly listingsService: ListingsService) {}
 
  @Query(() => [Listing], { name: 'listings' })
  async listings(
    @Args('filter', { type: () => ListingsFilterDto, nullable: true })
    filter?: ListingsFilterDto,
  ): Promise<Listing[]> {
    const sanitized = filter ? sanitizeInput(filter) : undefined;
    return this.listingsService.findAll(sanitized);
  }
 
  @Query(() => Listing, { name: 'listing', nullable: true })
  async listing(
    @Args('id', { type: () => Int }) id: number,
  ): Promise<Listing | null> {
    const sanitizedId = typeof id === 'string' ? sanitizeInput(id) : id;
    return this.listingsService.findOne(sanitizedId);
  }
 
  @Mutation(() => Listing)
  @UseGuards(GqlAuthGuard, RolesGuard)
  @Roles('ADMIN', 'AGENT')
  async createListing(
    @Args('createListingInput') createListingInput: CreateListingInput,
    @CurrentUser() user: any,
  ): Promise<Listing> {
    return this.listingsService.create(createListingInput, user.id);
  }
 
  @Mutation(() => Listing)
  @UseGuards(GqlAuthGuard, RolesGuard)
  @Roles('ADMIN', 'AGENT')
  async updateListing(
    @Args('id', { type: () => Int }) id: number,
    @Args('updateListingInput') updateListingInput: UpdateListingInput,
  ): Promise<Listing | null> {
    return this.listingsService.update(id, updateListingInput);
  }
 
  @Mutation(() => Boolean)
  @UseGuards(GqlAuthGuard, RolesGuard)
  @Roles('ADMIN', 'AGENT')
  async deleteListing(
    @Args('id', { type: () => Int }) id: number,
  ): Promise<boolean> {
    await this.listingsService.remove(id);
    return true;
  }
 
  // Additional lifecycle mutations for parity
  @Mutation(() => Listing)
  @UseGuards(GqlAuthGuard, RolesGuard)
  @Roles('ADMIN', 'AGENT')
  async publishListing(
    @Args('id', { type: () => Int }) id: number,
    @CurrentUser() user: any,
  ): Promise<Listing> {
    return this.listingsService.publish(id, user);
  }
 
  @Mutation(() => Listing)
  @UseGuards(GqlAuthGuard, RolesGuard)
  @Roles('ADMIN', 'AGENT')
  async unpublishListing(
    @Args('id', { type: () => Int }) id: number,
    @CurrentUser() user: any,
  ): Promise<Listing> {
    return this.listingsService.unpublish(id, user.id);
  }
 
  @Mutation(() => Listing)
  @UseGuards(GqlAuthGuard, RolesGuard)
  @Roles('ADMIN', 'AGENT')
  async archiveListing(
    @Args('id', { type: () => Int }) id: number,
    @CurrentUser() user: any,
  ): Promise<Listing> {
    return this.listingsService.archive(id, user.id);
  }
}