import { HTTPNoBody } from '@fastify-modular/route'; import { pito } from 'pito'; import { CardinalPoint } from '../enums'; import { KaptDefine, LatLongDefine, PriceDefine, TitleDefine } from '../types'; import { DatetimeMultiRangeDefine, IntMultiRangeDefine, NumMultiRangeDefine } from '../types/range'; // ========================================================================== export const BoundElementsDefine = pito.Obj({ addressId: pito.Str(), products : pito.Arr( pito.Obj({ id : pito.Num(), address: pito.UUID(), price : PriceDefine, }), ), // 집계 데이터 // 만약, 집계할 데이터가 없다면 undefined로 설정됨 statistics: pito.Obj({ // 월세 집계 monthly: pito.Opt(pito.Obj({ repr: pito.Obj({ price: pito.Num(), area : pito.Num(), }), count : pito.Num({ minimum: 1 }), // 보증금 집계 minDeposit: pito.Num(), maxDeposit: pito.Num(), avgDeposit: pito.Num(), // 월세 집계 minPrice : pito.Num(), maxPrice : pito.Num(), avgPrice : pito.Num(), })), // 전세 집계 charter: pito.Opt(pito.Obj({ repr: pito.Obj({ price: pito.Num(), area : pito.Num(), }), count: pito.Num({ minimum: 1 }), min : pito.Num(), max : pito.Num(), avg : pito.Num(), })), // 매매 집계 sale: pito.Opt(pito.Obj({ repr: pito.Obj({ price: pito.Num(), area : pito.Num(), }), count: pito.Num({ minimum: 1 }), min : pito.Num(), max : pito.Num(), avg : pito.Num(), })), }), // kapt : pito.Opt(KaptDefine), title : pito.Opt(TitleDefine), position: LatLongDefine, }); export type BoundElementsDefine = pito.Type; // ========================================================================== export const FindByBoundOutput = pito.Obj({ found: pito.Arr(BoundElementsDefine), }); export type FindByBoundOutput = pito.Type; // ========================================================================== export const FindByBoundOption = pito.Obj({ alat : pito.Num({ minimum: -90, maximum: 90 }), along : pito.Num({ minimum: -180, maximum: 180 }), blat : pito.Num({ minimum: -90, maximum: 90 }), blong : pito.Num({ minimum: -180, maximum: 180 }), // filterPrice: pito.Opt(pito.Uobj('type') // | 가격 종류 .case('sale-charter', ({ price: NumMultiRangeDefine, })) .case('sale', ({ price: NumMultiRangeDefine, })) .case('charter', ({ price: NumMultiRangeDefine, })) .case('monthly', ({ price: NumMultiRangeDefine, deposit: NumMultiRangeDefine, })) .end(), ), filterArea : pito.Opt(NumMultiRangeDefine), // | 면적 크기제한 filterApproval : pito.Opt(DatetimeMultiRangeDefine), // | 사용승인일 filterHhldCount : pito.Opt(IntMultiRangeDefine), // | 세대수 필터 filterFloor : pito.Opt(NumMultiRangeDefine), // | 층수 (%배열), // | 라벨 | 범위 표기 | 실제 데이터 // | - 1층 | [0 , 0 ] | { min:0 , max:0 , } // | - 저층 | (0 , 0.33] | { min:0 , max:0.33, exclusiveMin:true } // | - 중층 | (0.33, 0.66) | { min:0.33, max:0.66, exclusiveMin:true, exclusiveMax:true} // | - 고층 | [0.66, 1 ) | { min:0.66, max:1 , exclusiveMax:true } // | - 탑층 | [1 , 1 ] | { min:1 , max:1 , } // | 이런 식으로 보낼 것. // filterRoomCnt : pito.Opt(IntMultiRangeDefine), // | 방 개수 filterBathroomCnt: pito.Opt(IntMultiRangeDefine), // | 화장실 개수 filterCardinal : pito.Opt(pito.Arr(pito.Enums(CardinalPoint))), // | 창문방향 filterMncst : pito.Opt(NumMultiRangeDefine), // | 관리비 범위 withKapt : pito.Opt(pito.Bool()), withTitle : pito.Opt(pito.Bool()), pageSize : pito.Opt(pito.Int({ minimum: 0, maximum: 100 })), pageNo : pito.Opt(pito.Int({ minimum: 1 })), }); export type FindByBoundOption = pito.Type; // ========================================================================== export const FindByBound = HTTPNoBody('GET', '/api/v1/search/find-by-bound', 'search') .query(FindByBoundOption) .response(FindByBoundOutput) .build(); // ==========================================================================