Skip to content

Commit 322947f

Browse files
authored
Merge pull request #247 from map-of-pi/feature/search-filtering
Approved (1).
2 parents 7bc82ae + 6800c43 commit 322947f

File tree

13 files changed

+447
-264
lines changed

13 files changed

+447
-264
lines changed

src/config/docs/UserPreferencesSchema.yml

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,38 @@ components:
3939
required:
4040
- type
4141
- coordinates
42+
search_filters:
43+
type: object
44+
properties:
45+
include_active_sellers:
46+
type: boolean
47+
example: true
48+
include_inactive_sellers:
49+
type: boolean
50+
example: false
51+
include_test_sellers:
52+
type: boolean
53+
example: false
54+
include_trust_level_100:
55+
type: boolean
56+
example: true
57+
include_trust_level_80:
58+
type: boolean
59+
example: true
60+
include_trust_level_50:
61+
type: boolean
62+
example: true
63+
include_trust_level_0:
64+
type: boolean
65+
example: false
66+
required:
67+
- include_active_sellers
68+
- include_inactive_sellers
69+
- include_test_sellers
70+
- include_trust_level_100
71+
- include_trust_level_80
72+
- include_trust_level_50
73+
- include_trust_level_0
4274
_id:
4375
type: string
4476
example: 6673a08503852cb0c9b618d9
@@ -85,6 +117,38 @@ components:
85117
required:
86118
- type
87119
- coordinates
120+
search_filters:
121+
type: object
122+
properties:
123+
include_active_sellers:
124+
type: boolean
125+
example: true
126+
include_inactive_sellers:
127+
type: boolean
128+
example: false
129+
include_test_sellers:
130+
type: boolean
131+
example: false
132+
include_trust_level_100:
133+
type: boolean
134+
example: true
135+
include_trust_level_80:
136+
type: boolean
137+
example: true
138+
include_trust_level_50:
139+
type: boolean
140+
example: true
141+
include_trust_level_0:
142+
type: boolean
143+
example: false
144+
required:
145+
- include_active_sellers
146+
- include_inactive_sellers
147+
- include_test_sellers
148+
- include_trust_level_100
149+
- include_trust_level_80
150+
- include_trust_level_50
151+
- include_trust_level_0
88152
required:
89153
- user_settings_id
90154

@@ -127,6 +191,38 @@ components:
127191
required:
128192
- type
129193
- coordinates
194+
search_filters:
195+
type: object
196+
properties:
197+
include_active_sellers:
198+
type: boolean
199+
example: true
200+
include_inactive_sellers:
201+
type: boolean
202+
example: false
203+
include_test_sellers:
204+
type: boolean
205+
example: false
206+
include_trust_level_100:
207+
type: boolean
208+
example: true
209+
include_trust_level_80:
210+
type: boolean
211+
example: true
212+
include_trust_level_50:
213+
type: boolean
214+
example: true
215+
include_trust_level_0:
216+
type: boolean
217+
example: false
218+
required:
219+
- include_active_sellers
220+
- include_inactive_sellers
221+
- include_test_sellers
222+
- include_trust_level_100
223+
- include_trust_level_80
224+
- include_trust_level_50
225+
- include_trust_level_0
130226
_id:
131227
type: string
132228
example: 66741c62b175e7d059a2639e
@@ -181,6 +277,38 @@ components:
181277
required:
182278
- type
183279
- coordinates
280+
search_filters:
281+
type: object
282+
properties:
283+
include_active_sellers:
284+
type: boolean
285+
example: true
286+
include_inactive_sellers:
287+
type: boolean
288+
example: false
289+
include_test_sellers:
290+
type: boolean
291+
example: false
292+
include_trust_level_100:
293+
type: boolean
294+
example: true
295+
include_trust_level_80:
296+
type: boolean
297+
example: true
298+
include_trust_level_50:
299+
type: boolean
300+
example: true
301+
include_trust_level_0:
302+
type: boolean
303+
example: false
304+
required:
305+
- include_active_sellers
306+
- include_inactive_sellers
307+
- include_test_sellers
308+
- include_trust_level_100
309+
- include_trust_level_80
310+
- include_trust_level_50
311+
- include_trust_level_0
184312
_id:
185313
type: string
186314
example: 666c84b9d77068c6efeeaa1a

src/controllers/sellerController.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import logger from "../config/loggingConfig";
88
export const fetchSellersByCriteria = async (req: Request, res: Response) => {
99
try {
1010
const { bounds, search_query } = req.body; // bounds: [sw_lat, sw_lng, ne_lat, ne_lng]
11-
const sellers = await sellerService.getAllSellers(bounds, search_query);
11+
const userId = req.currentUser?.pi_uid;
12+
const sellers = await sellerService.getAllSellers(bounds, search_query, userId);
1213

1314
if (!sellers || sellers.length === 0) {
1415
logger.warn(`No sellers found within bounds (${bounds?.sw_lat}, ${bounds?.sw_lng}) to (${bounds?.ne_lat}, ${bounds?.ne_lng}) with "${search_query ?? 'undefined'}"`);

src/models/Seller.ts

Lines changed: 73 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,84 @@
1-
import mongoose, { Schema, Types } from "mongoose";
1+
import mongoose, { Schema, Types } from "mongoose";
22

3-
import { ISeller } from "../types";
4-
import { SellerType, VisibleSellerType, FulfillmentType } from "./enums/sellerType";
3+
import { ISeller } from "../types";
4+
import { SellerType } from "./enums/sellerType";
5+
import { FulfillmentType } from "./enums/fulfillmentType";
56

6-
const sellerSchema = new Schema<ISeller>(
7-
{
8-
seller_id: {
9-
type: String,
10-
required: true,
11-
unique: true,
12-
},
13-
name: {
7+
const sellerSchema = new Schema<ISeller>(
8+
{
9+
seller_id: {
10+
type: String,
11+
required: true,
12+
unique: true,
13+
},
14+
name: {
15+
type: String,
16+
required: true,
17+
},
18+
seller_type: {
19+
type: String,
20+
enum: Object.values(SellerType).filter(value => typeof value === 'string'),
21+
required: true,
22+
default: SellerType.Test,
23+
},
24+
description: {
25+
type: String,
26+
required: false,
27+
},
28+
image: {
29+
type: String,
30+
required: false,
31+
},
32+
address: {
33+
type: String,
34+
required: false,
35+
},
36+
average_rating: {
37+
type: Types.Decimal128,
38+
required: true,
39+
default: 5.0,
40+
},
41+
sell_map_center: {
42+
type: {
1443
type: String,
44+
enum: ['Point'],
1545
required: true,
46+
default: 'Point',
1647
},
17-
seller_type: {
18-
type: String,
19-
enum: Object.values(SellerType).filter(value => typeof value === 'string'),
48+
coordinates: {
49+
type: [Number],
2050
required: true,
21-
default: SellerType.Test,
22-
},
23-
description: {
24-
type: String,
25-
required: false,
51+
default: [0, 0]
2652
},
27-
image: {
28-
type: String,
29-
required: false,
30-
},
31-
address: {
32-
type: String,
33-
required: false,
34-
},
35-
average_rating: {
36-
type: Types.Decimal128,
37-
required: true,
38-
default: 5.0,
39-
},
40-
sell_map_center: {
41-
type: {
42-
type: String,
43-
enum: ['Point'],
44-
required: true,
45-
default: 'Point',
46-
},
47-
coordinates: {
48-
type: [Number],
49-
required: true,
50-
default: [0, 0]
51-
},
52-
},
53-
order_online_enabled_pref: {
54-
type: Boolean,
55-
required: false,
56-
},
57-
fulfillment_method: {
58-
type: String,
59-
enum: Object.values(FulfillmentType).filter(value => typeof value === 'string'),
60-
default: FulfillmentType.CollectionByBuyer
61-
},
62-
fulfillment_description: {
63-
type: String,
64-
default: null,
65-
required: false
66-
}
6753
},
68-
{ timestamps: true } // Adds timestamps to track creation and update times
69-
);
54+
order_online_enabled_pref: {
55+
type: Boolean,
56+
required: false,
57+
},
58+
fulfillment_method: {
59+
type: String,
60+
enum: Object.values(FulfillmentType).filter(value => typeof value === 'string'),
61+
default: FulfillmentType.CollectionByBuyer
62+
},
63+
fulfillment_description: {
64+
type: String,
65+
default: null,
66+
required: false
67+
}
68+
},
69+
{ timestamps: true } // Adds timestamps to track creation and update times
70+
);
71+
72+
// Creating a text index on the 'name' and 'description' fields
73+
sellerSchema.index({ name: "text", description: "text" });
7074

71-
// Creating a 2dsphere index for the sell_map_center field
72-
sellerSchema.index({ 'sell_map_center.coordinates': '2dsphere' });
73-
sellerSchema.index(
74-
{ 'updatedAt': -1, 'sell_map_center.coordinates': '2dsphere' },
75-
{ partialFilterExpression: { seller_type: { $in: Object.values(VisibleSellerType) } } }
76-
);
75+
// Creating a 2dsphere index for the sell_map_center field
76+
sellerSchema.index({ 'sell_map_center.coordinates': '2dsphere' });
77+
sellerSchema.index(
78+
{ 'updatedAt': -1, 'sell_map_center.coordinates': '2dsphere' }
79+
);
7780

78-
// Creating the Seller model from the schema
79-
const Seller = mongoose.model<ISeller>("Seller", sellerSchema);
81+
// Creating the Seller model from the schema
82+
const Seller = mongoose.model<ISeller>("Seller", sellerSchema);
8083

81-
export default Seller;
84+
export default Seller;

src/models/UserSettings.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,20 @@ const userSettingsSchema = new Schema<IUserSettings>(
5454
required: false,
5555
default: [0, 0]
5656
},
57-
}
57+
},
58+
search_filters: {
59+
type: {
60+
include_active_sellers: { type: Boolean, default: true },
61+
include_inactive_sellers: { type: Boolean, default: false },
62+
include_test_sellers: { type: Boolean, default: false },
63+
include_trust_level_100: { type: Boolean, default: true },
64+
include_trust_level_80: { type: Boolean, default: true },
65+
include_trust_level_50: { type: Boolean, default: true },
66+
include_trust_level_0: { type: Boolean, default: false },
67+
},
68+
required: true,
69+
default: {},
70+
},
5871
}
5972
);
6073

src/models/enums/fulfillmentType.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export enum FulfillmentType {
2+
CollectionByBuyer = 'Collection by buyer',
3+
DeliveredToBuyer = 'Delivered to buyer'
4+
}

src/models/enums/sellerType.ts

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,5 @@
1-
export enum VisibleSellerType {
1+
export enum SellerType {
22
Active = 'activeSeller',
3+
Inactive = 'inactiveSeller',
34
Test = 'testSeller'
45
}
5-
6-
enum InvisibleSellerType {
7-
Inactive = 'inactiveSeller'
8-
}
9-
10-
export const SellerType = Object.assign({}, VisibleSellerType, InvisibleSellerType);
11-
export type SellerType = VisibleSellerType | InvisibleSellerType;
12-
13-
export enum FulfillmentType {
14-
CollectionByBuyer = 'Collection by buyer',
15-
DeliveredToBuyer = 'Delivered to buyer'
16-
}

src/routes/seller.routes.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ const sellerRoutes = Router();
111111
* post:
112112
* tags:
113113
* - Seller
114-
* summary: Fetch all sellers within the visible map area (bounding box) | sorted by reviews with a maximum of 36 sellers.
114+
* summary: Fetch all filtered sellers within the visible map area (bounding box) | sorted by reviews with a maximum of 50 sellers *
115115
* requestBody:
116116
* content:
117117
* application/json:
@@ -133,7 +133,7 @@ const sellerRoutes = Router();
133133
* 500:
134134
* description: Internal server error
135135
*/
136-
sellerRoutes.post("/fetch", sellerController.fetchSellersByCriteria);
136+
sellerRoutes.post("/fetch", verifyToken, sellerController.fetchSellersByCriteria);
137137

138138
/**
139139
* @swagger

0 commit comments

Comments
 (0)