Abdul Rehman commited on
Commit
ae1ae66
·
1 Parent(s): 3d851fb

first commit

Browse files
Files changed (50) hide show
  1. .eslintrc.js +25 -0
  2. .gitignore +56 -0
  3. .history/src/modules/property/property.controller_20240903221404.ts +100 -0
  4. .history/src/modules/property/property.controller_20240904225916.ts +100 -0
  5. .history/src/modules/property/property.controller_20240904230453.ts +100 -0
  6. .history/src/modules/property/property.controller_20240904230611.ts +100 -0
  7. .history/src/modules/property/property.controller_20240904230817.ts +100 -0
  8. .history/src/modules/property/property.service_20240903213534.ts +44 -0
  9. .history/src/modules/property/property.service_20240904230816.ts +44 -0
  10. .prettierrc +4 -0
  11. README.md +85 -1
  12. nest-cli.json +8 -0
  13. package-lock.json +0 -0
  14. package.json +82 -0
  15. src/app.controller.spec.ts +22 -0
  16. src/app.controller.ts +12 -0
  17. src/app.module.ts +17 -0
  18. src/app.service.ts +8 -0
  19. src/constants/collections.constant.ts +2 -0
  20. src/constants/index.ts +2 -0
  21. src/constants/jwt.constant.ts +4 -0
  22. src/constants/repository.constant.ts +2 -0
  23. src/locales/en.ts +9 -0
  24. src/main.ts +23 -0
  25. src/modules/auth/auth.controller.ts +113 -0
  26. src/modules/auth/auth.module.ts +27 -0
  27. src/modules/auth/auth.service.ts +107 -0
  28. src/modules/auth/jwt-auth.guard.ts +18 -0
  29. src/modules/auth/jwt.strategy.ts +30 -0
  30. src/modules/auth/local-auth.guard.ts +5 -0
  31. src/modules/auth/local.strategy.ts +37 -0
  32. src/modules/database/database.module.ts +10 -0
  33. src/modules/database/database.provider.ts +12 -0
  34. src/modules/property/property.controller.ts +100 -0
  35. src/modules/property/property.module.ts +12 -0
  36. src/modules/property/property.provider.ts +12 -0
  37. src/modules/property/property.schema.ts +34 -0
  38. src/modules/property/property.service.ts +44 -0
  39. src/modules/shared/common.service.ts +27 -0
  40. src/modules/shared/sharedCrud.services.ts +28 -0
  41. src/modules/user/user.controller.ts +49 -0
  42. src/modules/user/user.dto.ts +55 -0
  43. src/modules/user/user.module.ts +13 -0
  44. src/modules/user/user.provider.ts +11 -0
  45. src/modules/user/user.schema.ts +78 -0
  46. src/modules/user/user.service.ts +25 -0
  47. test/app.e2e-spec.ts +24 -0
  48. test/jest-e2e.json +9 -0
  49. tsconfig.build.json +4 -0
  50. tsconfig.json +21 -0
.eslintrc.js ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ module.exports = {
2
+ parser: '@typescript-eslint/parser',
3
+ parserOptions: {
4
+ project: 'tsconfig.json',
5
+ tsconfigRootDir: __dirname,
6
+ sourceType: 'module',
7
+ },
8
+ plugins: ['@typescript-eslint/eslint-plugin'],
9
+ extends: [
10
+ 'plugin:@typescript-eslint/recommended',
11
+ 'plugin:prettier/recommended',
12
+ ],
13
+ root: true,
14
+ env: {
15
+ node: true,
16
+ jest: true,
17
+ },
18
+ ignorePatterns: ['.eslintrc.js'],
19
+ rules: {
20
+ '@typescript-eslint/interface-name-prefix': 'off',
21
+ '@typescript-eslint/explicit-function-return-type': 'off',
22
+ '@typescript-eslint/explicit-module-boundary-types': 'off',
23
+ '@typescript-eslint/no-explicit-any': 'off',
24
+ },
25
+ };
.gitignore ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # compiled output
2
+ /dist
3
+ /node_modules
4
+ /build
5
+
6
+ # Logs
7
+ logs
8
+ *.log
9
+ npm-debug.log*
10
+ pnpm-debug.log*
11
+ yarn-debug.log*
12
+ yarn-error.log*
13
+ lerna-debug.log*
14
+
15
+ # OS
16
+ .DS_Store
17
+
18
+ # Tests
19
+ /coverage
20
+ /.nyc_output
21
+
22
+ # IDEs and editors
23
+ /.idea
24
+ .project
25
+ .classpath
26
+ .c9/
27
+ *.launch
28
+ .settings/
29
+ *.sublime-workspace
30
+
31
+ # IDE - VSCode
32
+ .vscode/*
33
+ !.vscode/settings.json
34
+ !.vscode/tasks.json
35
+ !.vscode/launch.json
36
+ !.vscode/extensions.json
37
+
38
+ # dotenv environment variable files
39
+ .env
40
+ .env.development.local
41
+ .env.test.local
42
+ .env.production.local
43
+ .env.local
44
+
45
+ # temp directory
46
+ .temp
47
+ .tmp
48
+
49
+ # Runtime data
50
+ pids
51
+ *.pid
52
+ *.seed
53
+ *.pid.lock
54
+
55
+ # Diagnostic reports (https://nodejs.org/api/report.html)
56
+ report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
.history/src/modules/property/property.controller_20240903221404.ts ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {
2
+ Body,
3
+ Controller,
4
+ Get,
5
+ HttpStatus,
6
+ Post,
7
+ Query,
8
+ Req,
9
+ Res,
10
+ UseGuards,
11
+ } from '@nestjs/common';
12
+ import { Response } from 'express';
13
+ import { CommonServices } from '../shared/common.service';
14
+ import { PropertyService } from './property.service';
15
+
16
+ @Controller('property')
17
+ export class PropertyController extends CommonServices {
18
+ constructor(private readonly propertyService: PropertyService) {
19
+ super();
20
+ }
21
+
22
+ @Get('')
23
+ async getPropertListings(@Res() res: Response, @Req() req): Promise<any> {
24
+ try {
25
+ const response = await this.propertyService.sharedFind({});
26
+ return this.sendResponse(
27
+ this.messages.Success,
28
+ response ?? 'NOT_FOUND',
29
+ HttpStatus.OK,
30
+ res,
31
+ );
32
+ } catch (error) {
33
+ return this.sendResponse(
34
+ 'Internal server Error',
35
+ {},
36
+ HttpStatus.INTERNAL_SERVER_ERROR,
37
+ res,
38
+ );
39
+ }
40
+ }
41
+
42
+ /**
43
+ *
44
+ * @param query
45
+ * @param res
46
+ * @param req
47
+ */
48
+ @Get('/listings/dashboard')
49
+ async getDashboardLisings(@Res() res, @Req() req) {
50
+ try {
51
+ const listings = await this.propertyService.propertyRepository
52
+ .find({})
53
+ .sort({ _id: -1 })
54
+ .limit(20);
55
+
56
+ this.sendResponse(this.messages.Success, listings, HttpStatus.OK, res);
57
+ } catch (error) {
58
+ console.error('error', error);
59
+ this.sendResponse(
60
+ this.messages.Error,
61
+ null,
62
+ HttpStatus.INTERNAL_SERVER_ERROR,
63
+ res,
64
+ );
65
+ }
66
+ }
67
+
68
+ /**
69
+ *
70
+ * @param query
71
+ * @param res
72
+ * @param req
73
+ */
74
+ @Get('/listings')
75
+ async getDashboardActiveUsers(@Query() query, @Res() res, @Req() req) {
76
+ try {
77
+ const page = Number(query.page);
78
+ const resPerPage = query.resPerPage ? Number(query.resPerPage) : 20;
79
+ const search = query.search;
80
+
81
+ console.log(`search =>`, search);
82
+
83
+ const activeUsers = await this.propertyService.propertyLisitng(
84
+ page,
85
+ resPerPage,
86
+ search,
87
+ );
88
+
89
+ this.sendResponse(this.messages.Success, activeUsers, HttpStatus.OK, res);
90
+ } catch (error) {
91
+ console.error('error', error);
92
+ this.sendResponse(
93
+ this.messages.Error,
94
+ null,
95
+ HttpStatus.INTERNAL_SERVER_ERROR,
96
+ res,
97
+ );
98
+ }
99
+ }
100
+ }
.history/src/modules/property/property.controller_20240904225916.ts ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {
2
+ Body,
3
+ Controller,
4
+ Get,
5
+ HttpStatus,
6
+ Post,
7
+ Query,
8
+ Req,
9
+ Res,
10
+ UseGuards,
11
+ } from '@nestjs/common';
12
+ import { Response } from 'express';
13
+ import { CommonServices } from '../shared/common.service';
14
+ import { PropertyService } from './property.service';
15
+
16
+ @Controller('property')
17
+ export class PropertyController extends CommonServices {
18
+ constructor(private readonly propertyService: PropertyService) {
19
+ super();
20
+ }
21
+
22
+ @Get('')
23
+ async getPropertListings(@Res() res: Response, @Req() req): Promise<any> {
24
+ try {
25
+ const response = await this.propertyService.sharedFind({});
26
+ return this.sendResponse(
27
+ this.messages.Success,
28
+ response ?? 'NOT_FOUND',
29
+ HttpStatus.OK,
30
+ res,
31
+ );
32
+ } catch (error) {
33
+ return this.sendResponse(
34
+ 'Internal server Error',
35
+ {},
36
+ HttpStatus.INTERNAL_SERVER_ERROR,
37
+ res,
38
+ );
39
+ }
40
+ }
41
+
42
+ /**
43
+ *
44
+ * @param query
45
+ * @param res
46
+ * @param req
47
+ */
48
+ @Get('/listings/dashboard')
49
+ async getDashboardLisings(@Res() res, @Req() req) {
50
+ try {
51
+ const listings = await this.propertyService.propertyRepository
52
+ .find({})
53
+ .sort({ _id: -1 })
54
+ .limit(20);
55
+
56
+ this.sendResponse(this.messages.Success, listings, HttpStatus.OK, res);
57
+ } catch (error) {
58
+ console.error('error', error);
59
+ this.sendResponse(
60
+ this.messages.Error,
61
+ null,
62
+ HttpStatus.INTERNAL_SERVER_ERROR,
63
+ res,
64
+ );
65
+ }
66
+ }
67
+
68
+ /**
69
+ *
70
+ * @param query
71
+ * @param res
72
+ * @param req
73
+ */
74
+ @Get('/listings')
75
+ async getDashboardActiveUsers(@Query() query, @Res() res, @Req() req) {
76
+ try {
77
+ const page = Number(query.page);
78
+ const resPerPage = query.resPerPage ? Number(query.resPerPage) : 20;
79
+ const search = query.search;
80
+
81
+ console.log(`search =>`, query);
82
+
83
+ const activeUsers = await this.propertyService.propertyLisitng(
84
+ page,
85
+ resPerPage,
86
+ search,
87
+ );
88
+
89
+ this.sendResponse(this.messages.Success, activeUsers, HttpStatus.OK, res);
90
+ } catch (error) {
91
+ console.error('error', error);
92
+ this.sendResponse(
93
+ this.messages.Error,
94
+ null,
95
+ HttpStatus.INTERNAL_SERVER_ERROR,
96
+ res,
97
+ );
98
+ }
99
+ }
100
+ }
.history/src/modules/property/property.controller_20240904230453.ts ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {
2
+ Body,
3
+ Controller,
4
+ Get,
5
+ HttpStatus,
6
+ Post,
7
+ Query,
8
+ Req,
9
+ Res,
10
+ UseGuards,
11
+ } from '@nestjs/common';
12
+ import { Response } from 'express';
13
+ import { CommonServices } from '../shared/common.service';
14
+ import { PropertyService } from './property.service';
15
+
16
+ @Controller('property')
17
+ export class PropertyController extends CommonServices {
18
+ constructor(private readonly propertyService: PropertyService) {
19
+ super();
20
+ }
21
+
22
+ @Get('')
23
+ async getPropertListings(@Res() res: Response, @Req() req): Promise<any> {
24
+ try {
25
+ const response = await this.propertyService.sharedFind({});
26
+ return this.sendResponse(
27
+ this.messages.Success,
28
+ response ?? 'NOT_FOUND',
29
+ HttpStatus.OK,
30
+ res,
31
+ );
32
+ } catch (error) {
33
+ return this.sendResponse(
34
+ 'Internal server Error',
35
+ {},
36
+ HttpStatus.INTERNAL_SERVER_ERROR,
37
+ res,
38
+ );
39
+ }
40
+ }
41
+
42
+ /**
43
+ *
44
+ * @param query
45
+ * @param res
46
+ * @param req
47
+ */
48
+ @Get('/listings/dashboard')
49
+ async getDashboardLisings(@Res() res, @Req() req) {
50
+ try {
51
+ const listings = await this.propertyService.propertyRepository
52
+ .find({})
53
+ .sort({ _id: -1 })
54
+ .limit(20);
55
+
56
+ this.sendResponse(this.messages.Success, listings, HttpStatus.OK, res);
57
+ } catch (error) {
58
+ console.error('error', error);
59
+ this.sendResponse(
60
+ this.messages.Error,
61
+ null,
62
+ HttpStatus.INTERNAL_SERVER_ERROR,
63
+ res,
64
+ );
65
+ }
66
+ }
67
+
68
+ /**
69
+ *
70
+ * @param query
71
+ * @param res
72
+ * @param req
73
+ */
74
+ @Get('/listings')
75
+ async getDashboardActiveUsers(@Query() query, @Res() res, @Req() req) {
76
+ try {
77
+ const page = Number(query.page);
78
+ const resPerPage = query.resPerPage ? Number(query.resPerPage) : 20;
79
+ const search = query.search || ''; // Default to empty search if not provided
80
+
81
+ console.log(`search =>`, query);
82
+
83
+ const activeUsers = await this.propertyService.propertyLisitng(
84
+ page,
85
+ resPerPage,
86
+ search,
87
+ );
88
+
89
+ this.sendResponse(this.messages.Success, activeUsers, HttpStatus.OK, res);
90
+ } catch (error) {
91
+ console.error('error', error);
92
+ this.sendResponse(
93
+ this.messages.Error,
94
+ null,
95
+ HttpStatus.INTERNAL_SERVER_ERROR,
96
+ res,
97
+ );
98
+ }
99
+ }
100
+ }
.history/src/modules/property/property.controller_20240904230611.ts ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {
2
+ Body,
3
+ Controller,
4
+ Get,
5
+ HttpStatus,
6
+ Post,
7
+ Query,
8
+ Req,
9
+ Res,
10
+ UseGuards,
11
+ } from '@nestjs/common';
12
+ import { Response } from 'express';
13
+ import { CommonServices } from '../shared/common.service';
14
+ import { PropertyService } from './property.service';
15
+
16
+ @Controller('property')
17
+ export class PropertyController extends CommonServices {
18
+ constructor(private readonly propertyService: PropertyService) {
19
+ super();
20
+ }
21
+
22
+ @Get('')
23
+ async getPropertListings(@Res() res: Response, @Req() req): Promise<any> {
24
+ try {
25
+ const response = await this.propertyService.sharedFind({});
26
+ return this.sendResponse(
27
+ this.messages.Success,
28
+ response ?? 'NOT_FOUND',
29
+ HttpStatus.OK,
30
+ res,
31
+ );
32
+ } catch (error) {
33
+ return this.sendResponse(
34
+ 'Internal server Error',
35
+ {},
36
+ HttpStatus.INTERNAL_SERVER_ERROR,
37
+ res,
38
+ );
39
+ }
40
+ }
41
+
42
+ /**
43
+ *
44
+ * @param query
45
+ * @param res
46
+ * @param req
47
+ */
48
+ @Get('/listings/dashboard')
49
+ async getDashboardLisings(@Res() res, @Req() req) {
50
+ try {
51
+ const listings = await this.propertyService.propertyRepository
52
+ .find({})
53
+ .sort({ _id: -1 })
54
+ .limit(20);
55
+
56
+ this.sendResponse(this.messages.Success, listings, HttpStatus.OK, res);
57
+ } catch (error) {
58
+ console.error('error', error);
59
+ this.sendResponse(
60
+ this.messages.Error,
61
+ null,
62
+ HttpStatus.INTERNAL_SERVER_ERROR,
63
+ res,
64
+ );
65
+ }
66
+ }
67
+
68
+ /**
69
+ *
70
+ * @param query
71
+ * @param res
72
+ * @param req
73
+ */
74
+ @Get('/listings')
75
+ async getDashboardActiveUsers(@Query() query, @Res() res, @Req() req) {
76
+ try {
77
+ const page = Number(query.page);
78
+ const resPerPage = query.resPerPage ? Number(query.resPerPage) : 20;
79
+ const search = query.search || ''; // Default to empty search if not provided
80
+
81
+ console.log(`search =>`, query);
82
+
83
+ const listings = await this.propertyService.propertyLisitng(
84
+ page,
85
+ resPerPage,
86
+ search,
87
+ );
88
+
89
+ this.sendResponse(this.messages.Success, listings, HttpStatus.OK, res);
90
+ } catch (error) {
91
+ console.error('error', error);
92
+ this.sendResponse(
93
+ this.messages.Error,
94
+ null,
95
+ HttpStatus.INTERNAL_SERVER_ERROR,
96
+ res,
97
+ );
98
+ }
99
+ }
100
+ }
.history/src/modules/property/property.controller_20240904230817.ts ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {
2
+ Body,
3
+ Controller,
4
+ Get,
5
+ HttpStatus,
6
+ Post,
7
+ Query,
8
+ Req,
9
+ Res,
10
+ UseGuards,
11
+ } from '@nestjs/common';
12
+ import { Response } from 'express';
13
+ import { CommonServices } from '../shared/common.service';
14
+ import { PropertyService } from './property.service';
15
+
16
+ @Controller('property')
17
+ export class PropertyController extends CommonServices {
18
+ constructor(private readonly propertyService: PropertyService) {
19
+ super();
20
+ }
21
+
22
+ @Get('')
23
+ async getPropertListings(@Res() res: Response, @Req() req): Promise<any> {
24
+ try {
25
+ const response = await this.propertyService.sharedFind({});
26
+ return this.sendResponse(
27
+ this.messages.Success,
28
+ response ?? 'NOT_FOUND',
29
+ HttpStatus.OK,
30
+ res,
31
+ );
32
+ } catch (error) {
33
+ return this.sendResponse(
34
+ 'Internal server Error',
35
+ {},
36
+ HttpStatus.INTERNAL_SERVER_ERROR,
37
+ res,
38
+ );
39
+ }
40
+ }
41
+
42
+ /**
43
+ *
44
+ * @param query
45
+ * @param res
46
+ * @param req
47
+ */
48
+ @Get('/listings/dashboard')
49
+ async getDashboardLisings(@Res() res, @Req() req) {
50
+ try {
51
+ const listings = await this.propertyService.propertyRepository
52
+ .find({})
53
+ .sort({ _id: -1 })
54
+ .limit(20);
55
+
56
+ this.sendResponse(this.messages.Success, listings, HttpStatus.OK, res);
57
+ } catch (error) {
58
+ console.error('error', error);
59
+ this.sendResponse(
60
+ this.messages.Error,
61
+ null,
62
+ HttpStatus.INTERNAL_SERVER_ERROR,
63
+ res,
64
+ );
65
+ }
66
+ }
67
+
68
+ /**
69
+ *
70
+ * @param query
71
+ * @param res
72
+ * @param req
73
+ */
74
+ @Get('/listings')
75
+ async getDashboardActiveUsers(@Query() query, @Res() res, @Req() req) {
76
+ try {
77
+ const page = Number(query.page);
78
+ const resPerPage = query.resPerPage ? Number(query.resPerPage) : 20;
79
+ const search = query.search || ''; // Default to empty search if not provided
80
+
81
+ console.log(`search =>`, query);
82
+
83
+ const listings = await this.propertyService.propertyLisitng(
84
+ page,
85
+ resPerPage,
86
+ search,
87
+ );
88
+
89
+ this.sendResponse(this.messages.Success, listings, HttpStatus.OK, res);
90
+ } catch (error) {
91
+ console.error('error', error);
92
+ this.sendResponse(
93
+ this.messages.Error,
94
+ null,
95
+ HttpStatus.INTERNAL_SERVER_ERROR,
96
+ res,
97
+ );
98
+ }
99
+ }
100
+ }
.history/src/modules/property/property.service_20240903213534.ts ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Inject, Injectable } from '@nestjs/common';
2
+ import { Model, Types } from 'mongoose';
3
+ import { sharedCrudService } from '../shared/sharedCrud.services';
4
+ import { PROPERTY_REPOSITORY } from 'src/constants';
5
+ import { IPropertyDocument } from './property.schema';
6
+
7
+ @Injectable()
8
+ export class PropertyService extends sharedCrudService {
9
+ constructor(
10
+ @Inject(PROPERTY_REPOSITORY)
11
+ readonly propertyRepository: Model<IPropertyDocument>,
12
+ ) {
13
+ super(propertyRepository);
14
+ }
15
+
16
+ async propertyLisitng(
17
+ page: number,
18
+ resPerPage: number,
19
+ search: string,
20
+ ): Promise<any> {
21
+ const query = [];
22
+ query.push({ id: { $exists: true } });
23
+
24
+ if (search) query.push({ title: { $regex: search, $options: 'i' } });
25
+
26
+ const [users, cusersCount] = await Promise.all([
27
+ this.propertyRepository
28
+ .find({ $and: [...query] })
29
+ .sort({ createdAt: -1 })
30
+ .skip(resPerPage * (page - 1))
31
+ .limit(resPerPage)
32
+ .exec(),
33
+ this.propertyRepository.countDocuments({ $and: [...query] }).exec(),
34
+ ]);
35
+
36
+ return {
37
+ users,
38
+ current_page: page,
39
+ pages: Math.ceil(cusersCount / resPerPage),
40
+ total_users: cusersCount,
41
+ per_page: resPerPage,
42
+ };
43
+ }
44
+ }
.history/src/modules/property/property.service_20240904230816.ts ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Inject, Injectable } from '@nestjs/common';
2
+ import { Model, Types } from 'mongoose';
3
+ import { sharedCrudService } from '../shared/sharedCrud.services';
4
+ import { PROPERTY_REPOSITORY } from 'src/constants';
5
+ import { IPropertyDocument } from './property.schema';
6
+
7
+ @Injectable()
8
+ export class PropertyService extends sharedCrudService {
9
+ constructor(
10
+ @Inject(PROPERTY_REPOSITORY)
11
+ readonly propertyRepository: Model<IPropertyDocument>,
12
+ ) {
13
+ super(propertyRepository);
14
+ }
15
+
16
+ async propertyLisitng(
17
+ page: number,
18
+ resPerPage: number,
19
+ search: string,
20
+ ): Promise<any> {
21
+ const query = [];
22
+ query.push({ id: { $exists: true } });
23
+
24
+ if (search) query.push({ title: { $regex: search, $options: 'i' } });
25
+
26
+ const [listings, tLisitngsCount] = await Promise.all([
27
+ this.propertyRepository
28
+ .find({ $and: [...query] })
29
+ .sort({ createdAt: -1 })
30
+ .skip(resPerPage * (page - 1))
31
+ .limit(resPerPage)
32
+ .exec(),
33
+ this.propertyRepository.countDocuments({ $and: [...query] }).exec(),
34
+ ]);
35
+
36
+ return {
37
+ listings,
38
+ current_page: page,
39
+ pages: Math.ceil(tLisitngsCount / resPerPage),
40
+ total_listings: tLisitngsCount,
41
+ per_page: resPerPage,
42
+ };
43
+ }
44
+ }
.prettierrc ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ {
2
+ "singleQuote": true,
3
+ "trailingComma": "all"
4
+ }
README.md CHANGED
@@ -1 +1,85 @@
1
- # real-estate
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <p align="center">
2
+ <a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo-small.svg" width="120" alt="Nest Logo" /></a>
3
+ </p>
4
+
5
+ [circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456
6
+ [circleci-url]: https://circleci.com/gh/nestjs/nest
7
+
8
+ <p align="center">A progressive <a href="http://nodejs.org" target="_blank">Node.js</a> framework for building efficient and scalable server-side applications.</p>
9
+ <p align="center">
10
+ <a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a>
11
+ <a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/l/@nestjs/core.svg" alt="Package License" /></a>
12
+ <a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/dm/@nestjs/common.svg" alt="NPM Downloads" /></a>
13
+ <a href="https://circleci.com/gh/nestjs/nest" target="_blank"><img src="https://img.shields.io/circleci/build/github/nestjs/nest/master" alt="CircleCI" /></a>
14
+ <a href="https://coveralls.io/github/nestjs/nest?branch=master" target="_blank"><img src="https://coveralls.io/repos/github/nestjs/nest/badge.svg?branch=master#9" alt="Coverage" /></a>
15
+ <a href="https://discord.gg/G7Qnnhy" target="_blank"><img src="https://img.shields.io/badge/discord-online-brightgreen.svg" alt="Discord"/></a>
16
+ <a href="https://opencollective.com/nest#backer" target="_blank"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a>
17
+ <a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a>
18
+ <a href="https://paypal.me/kamilmysliwiec" target="_blank"><img src="https://img.shields.io/badge/Donate-PayPal-ff3f59.svg" alt="Donate us"/></a>
19
+ <a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://img.shields.io/badge/Support%20us-Open%20Collective-41B883.svg" alt="Support us"></a>
20
+ <a href="https://twitter.com/nestframework" target="_blank"><img src="https://img.shields.io/twitter/follow/nestframework.svg?style=social&label=Follow" alt="Follow us on Twitter"></a>
21
+ </p>
22
+ <!--[![Backers on Open Collective](https://opencollective.com/nest/backers/badge.svg)](https://opencollective.com/nest#backer)
23
+ [![Sponsors on Open Collective](https://opencollective.com/nest/sponsors/badge.svg)](https://opencollective.com/nest#sponsor)-->
24
+
25
+ ## Description
26
+
27
+ [Nest](https://github.com/nestjs/nest) framework TypeScript starter repository.
28
+
29
+ ## Project setup
30
+
31
+ ```bash
32
+ $ npm install
33
+ ```
34
+
35
+ ## Compile and run the project
36
+
37
+ ```bash
38
+ # development
39
+ $ npm run start
40
+
41
+ # watch mode
42
+ $ npm run start:dev
43
+
44
+ # production mode
45
+ $ npm run start:prod
46
+ ```
47
+
48
+ ## Run tests
49
+
50
+ ```bash
51
+ # unit tests
52
+ $ npm run test
53
+
54
+ # e2e tests
55
+ $ npm run test:e2e
56
+
57
+ # test coverage
58
+ $ npm run test:cov
59
+ ```
60
+
61
+ ## Resources
62
+
63
+ Check out a few resources that may come in handy when working with NestJS:
64
+
65
+ - Visit the [NestJS Documentation](https://docs.nestjs.com) to learn more about the framework.
66
+ - For questions and support, please visit our [Discord channel](https://discord.gg/G7Qnnhy).
67
+ - To dive deeper and get more hands-on experience, check out our official video [courses](https://courses.nestjs.com/).
68
+ - Visualize your application graph and interact with the NestJS application in real-time using [NestJS Devtools](https://devtools.nestjs.com).
69
+ - Need help with your project (part-time to full-time)? Check out our official [enterprise support](https://enterprise.nestjs.com).
70
+ - To stay in the loop and get updates, follow us on [X](https://x.com/nestframework) and [LinkedIn](https://linkedin.com/company/nestjs).
71
+ - Looking for a job, or have a job to offer? Check out our official [Jobs board](https://jobs.nestjs.com).
72
+
73
+ ## Support
74
+
75
+ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
76
+
77
+ ## Stay in touch
78
+
79
+ - Author - [Kamil Myśliwiec](https://twitter.com/kammysliwiec)
80
+ - Website - [https://nestjs.com](https://nestjs.com/)
81
+ - Twitter - [@nestframework](https://twitter.com/nestframework)
82
+
83
+ ## License
84
+
85
+ Nest is [MIT licensed](https://github.com/nestjs/nest/blob/master/LICENSE).
nest-cli.json ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "$schema": "https://json.schemastore.org/nest-cli",
3
+ "collection": "@nestjs/schematics",
4
+ "sourceRoot": "src",
5
+ "compilerOptions": {
6
+ "deleteOutDir": true
7
+ }
8
+ }
package-lock.json ADDED
The diff for this file is too large to render. See raw diff
 
package.json ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "property",
3
+ "version": "0.0.1",
4
+ "description": "",
5
+ "author": "",
6
+ "private": true,
7
+ "license": "UNLICENSED",
8
+ "scripts": {
9
+ "build": "nest build",
10
+ "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
11
+ "start": "nest start",
12
+ "start:dev": "nest start --watch",
13
+ "start:debug": "nest start --debug --watch",
14
+ "start:prod": "node dist/main",
15
+ "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
16
+ "test": "jest",
17
+ "test:watch": "jest --watch",
18
+ "test:cov": "jest --coverage",
19
+ "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
20
+ "test:e2e": "jest --config ./test/jest-e2e.json"
21
+ },
22
+ "dependencies": {
23
+ "@nestjs/common": "^10.0.0",
24
+ "@nestjs/core": "^10.0.0",
25
+ "@nestjs/jwt": "^10.2.0",
26
+ "@nestjs/passport": "^10.0.3",
27
+ "@nestjs/platform-express": "^10.0.0",
28
+ "bcrypt": "^5.1.1",
29
+ "body-parser": "^1.20.2",
30
+ "class-transformer": "^0.5.1",
31
+ "class-validator": "^0.14.1",
32
+ "cors": "^2.8.5",
33
+ "i18n-ts": "^1.0.5",
34
+ "jwt-decode": "^4.0.0",
35
+ "mongoose": "^8.6.0",
36
+ "passport-custom": "^1.1.1",
37
+ "passport-jwt": "^4.0.1",
38
+ "passport-local": "^1.0.0",
39
+ "reflect-metadata": "^0.2.0",
40
+ "rxjs": "^7.8.1"
41
+ },
42
+ "devDependencies": {
43
+ "@nestjs/cli": "^10.0.0",
44
+ "@nestjs/schematics": "^10.0.0",
45
+ "@nestjs/testing": "^10.0.0",
46
+ "@types/express": "^4.17.17",
47
+ "@types/jest": "^29.5.2",
48
+ "@types/node": "^20.3.1",
49
+ "@types/supertest": "^6.0.0",
50
+ "@typescript-eslint/eslint-plugin": "^8.0.0",
51
+ "@typescript-eslint/parser": "^8.0.0",
52
+ "eslint": "^8.42.0",
53
+ "eslint-config-prettier": "^9.0.0",
54
+ "eslint-plugin-prettier": "^5.0.0",
55
+ "jest": "^29.5.0",
56
+ "prettier": "^3.0.0",
57
+ "source-map-support": "^0.5.21",
58
+ "supertest": "^7.0.0",
59
+ "ts-jest": "^29.1.0",
60
+ "ts-loader": "^9.4.3",
61
+ "ts-node": "^10.9.1",
62
+ "tsconfig-paths": "^4.2.0",
63
+ "typescript": "^5.1.3"
64
+ },
65
+ "jest": {
66
+ "moduleFileExtensions": [
67
+ "js",
68
+ "json",
69
+ "ts"
70
+ ],
71
+ "rootDir": "src",
72
+ "testRegex": ".*\\.spec\\.ts$",
73
+ "transform": {
74
+ "^.+\\.(t|j)s$": "ts-jest"
75
+ },
76
+ "collectCoverageFrom": [
77
+ "**/*.(t|j)s"
78
+ ],
79
+ "coverageDirectory": "../coverage",
80
+ "testEnvironment": "node"
81
+ }
82
+ }
src/app.controller.spec.ts ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Test, TestingModule } from '@nestjs/testing';
2
+ import { AppController } from './app.controller';
3
+ import { AppService } from './app.service';
4
+
5
+ describe('AppController', () => {
6
+ let appController: AppController;
7
+
8
+ beforeEach(async () => {
9
+ const app: TestingModule = await Test.createTestingModule({
10
+ controllers: [AppController],
11
+ providers: [AppService],
12
+ }).compile();
13
+
14
+ appController = app.get<AppController>(AppController);
15
+ });
16
+
17
+ describe('root', () => {
18
+ it('should return "Hello World!"', () => {
19
+ expect(appController.getHello()).toBe('Hello World!');
20
+ });
21
+ });
22
+ });
src/app.controller.ts ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Controller, Get } from '@nestjs/common';
2
+ import { AppService } from './app.service';
3
+
4
+ @Controller()
5
+ export class AppController {
6
+ constructor(private readonly appService: AppService) {}
7
+
8
+ @Get()
9
+ getHello(): string {
10
+ return this.appService.getHello();
11
+ }
12
+ }
src/app.module.ts ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Module } from '@nestjs/common';
2
+ import { AppController } from './app.controller';
3
+ import { AppService } from './app.service';
4
+ import { PropertyModule } from './modules/property/property.module';
5
+ import { AuthModule } from './modules/auth/auth.module';
6
+ import { UserModule } from './modules/user/user.module';
7
+
8
+ @Module({
9
+ imports: [
10
+ PropertyModule,
11
+ AuthModule,
12
+ UserModule,
13
+ ],
14
+ controllers: [AppController],
15
+ providers: [AppService],
16
+ })
17
+ export class AppModule {}
src/app.service.ts ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ import { Injectable } from '@nestjs/common';
2
+
3
+ @Injectable()
4
+ export class AppService {
5
+ getHello(): string {
6
+ return 'Hello World!';
7
+ }
8
+ }
src/constants/collections.constant.ts ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ export const PROPERTIE = 'propertie';
2
+ export const USERS = 'users';
src/constants/index.ts ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ export * from './collections.constant'
2
+ export * from './repository.constant'
src/constants/jwt.constant.ts ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ export const jwtConstants = {
2
+ secret: "secretKey",
3
+ salt: 10
4
+ };
src/constants/repository.constant.ts ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ export const PROPERTY_REPOSITORY = 'PROPERTY_REPOSITORY';
2
+ export const USER_REPOSITORY = 'USER_REPOSITORY';
src/locales/en.ts ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ export const en = {
2
+ Success: 'Operation is completed Success',
3
+ Error: 'Something Went Wrong',
4
+ adminVerificationFaild: 'Admin key verification failed',
5
+ friendAdded: 'Friend added Successfully.',
6
+ reqRejected: 'Friend request declined.',
7
+ friendReqSent: 'Friend request sent Successfully.',
8
+ userAlreadyExist: 'User already exist.',
9
+ };
src/main.ts ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { NestFactory } from '@nestjs/core';
2
+ import { AppModule } from './app.module';
3
+ import * as bodyParser from 'body-parser';
4
+ import { ValidationPipe } from '@nestjs/common';
5
+
6
+ async function bootstrap() {
7
+ const app = await NestFactory.create(AppModule);
8
+
9
+ app.useGlobalPipes(new ValidationPipe());
10
+
11
+ // Enable CORS for all origins and all methods
12
+ app.enableCors({
13
+ origin: '*', // Allow all origins
14
+ methods: '*', // Allow all methods
15
+ credentials: true,
16
+ });
17
+
18
+ app.use(bodyParser.urlencoded({ extended: true }));
19
+ app.use(bodyParser.json());
20
+
21
+ await app.listen(8080);
22
+ }
23
+ bootstrap();
src/modules/auth/auth.controller.ts ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {
2
+ Body,
3
+ Controller,
4
+ Get,
5
+ HttpStatus,
6
+ Inject,
7
+ Param,
8
+ Post,
9
+ Put,
10
+ Query,
11
+ Req,
12
+ Res,
13
+ UploadedFile,
14
+ UseGuards,
15
+ UseInterceptors,
16
+ } from '@nestjs/common';
17
+ import { Response, Request } from 'express';
18
+ import { AuthService } from './auth.service';
19
+ import * as bcrypt from 'bcrypt';
20
+ import { LocalAuthGuard } from './local-auth.guard';
21
+ import { UserService } from '../user/user.service';
22
+ import { JwtAuthGuard } from './jwt-auth.guard';
23
+ import * as jwt from 'jsonwebtoken';
24
+ import { FileInterceptor } from '@nestjs/platform-express';
25
+ import { Model } from 'mongoose';
26
+ import { AuthGuard } from '@nestjs/passport';
27
+ import { JwtService } from '@nestjs/jwt';
28
+ import { CommonServices } from '../shared/common.service';
29
+ import { jwtConstants } from 'src/constants/jwt.constant';
30
+
31
+ @Controller('auth')
32
+ export class AuthController extends CommonServices {
33
+ constructor(
34
+ private readonly authService: AuthService,
35
+ private readonly userService: UserService,
36
+ ) {
37
+ super();
38
+ }
39
+
40
+ @UseGuards(LocalAuthGuard)
41
+ @Post('/login')
42
+ async login(
43
+ @Req() req: any,
44
+ @Res() res: Response,
45
+ @Body() body: any,
46
+ ): Promise<any> {
47
+ try {
48
+ const Userresp: any = await this.authService.login(req.user, body);
49
+ return this.sendResponse(
50
+ this.messages.Success,
51
+ Userresp,
52
+ HttpStatus.OK,
53
+ res,
54
+ );
55
+ } catch (error) {
56
+ console.log(`error =>`, error);
57
+ return this.sendResponse(
58
+ 'Internal server Error',
59
+ {},
60
+ HttpStatus.INTERNAL_SERVER_ERROR,
61
+ res,
62
+ );
63
+ }
64
+ }
65
+
66
+ @Post('/signup')
67
+ async signup(
68
+ @Req() req: any,
69
+ @Res() res: Response,
70
+ @Body() body: any,
71
+ ): Promise<any> {
72
+ try {
73
+ const email = body.email.toLowerCase().trim();
74
+
75
+ const checkUser = await this.userService.sharedFindOne({ email: email });
76
+
77
+ if (checkUser && checkUser.email == email) {
78
+ return this.sendResponse(
79
+ this.messages.userAlreadyExist,
80
+ {},
81
+ HttpStatus.CONFLICT,
82
+ res,
83
+ );
84
+ }
85
+
86
+ const createUser = await this.userService.sharedCreate({
87
+ ...body,
88
+ password: bcrypt.hashSync(body.password, jwtConstants.salt),
89
+ roles: ['user'],
90
+ });
91
+
92
+ const Userresp: any = await this.authService.login(createUser);
93
+
94
+ return this.sendResponse(
95
+ 'Account created!',
96
+ {
97
+ ...Userresp,
98
+ },
99
+ HttpStatus.OK,
100
+ res,
101
+ );
102
+ } catch (error) {
103
+ console.log(error);
104
+
105
+ return this.sendResponse(
106
+ 'Internal server Error',
107
+ {},
108
+ HttpStatus.INTERNAL_SERVER_ERROR,
109
+ res,
110
+ );
111
+ }
112
+ }
113
+ }
src/modules/auth/auth.module.ts ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Module } from '@nestjs/common';
2
+ import { AuthService } from './auth.service';
3
+ import { UserModule } from '../user/user.module';
4
+ import { AuthController } from './auth.controller';
5
+ import { DatabaseModule } from '../database/database.module';
6
+ import { UserService } from '../user/user.service';
7
+ import { JwtModule } from '@nestjs/jwt';
8
+ import { PassportModule } from '@nestjs/passport';
9
+ import { jwtConstants } from 'src/constants/jwt.constant';
10
+ import { JwtStrategy } from './jwt.strategy';
11
+ import { LocalStrategy } from './local.strategy';
12
+
13
+ @Module({
14
+ imports: [
15
+ DatabaseModule,
16
+ UserModule,
17
+ PassportModule,
18
+ JwtModule.register({
19
+ secret: 'secretKey',
20
+ signOptions: { expiresIn: '60d' },
21
+ }),
22
+ ],
23
+ controllers: [AuthController],
24
+ providers: [AuthService, UserService, JwtStrategy, LocalStrategy],
25
+ exports: [AuthService, UserService],
26
+ })
27
+ export class AuthModule {}
src/modules/auth/auth.service.ts ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Injectable, Inject } from '@nestjs/common';
2
+ import * as bcrypt from 'bcrypt';
3
+ import { JwtService } from '@nestjs/jwt';
4
+ import { UserService } from '../user/user.service';
5
+ import { Model } from 'mongoose';
6
+ import { CommonServices } from '../shared/common.service';
7
+ var qs = require('qs');
8
+
9
+ @Injectable()
10
+ export class AuthService extends CommonServices {
11
+ constructor(
12
+ private readonly userService: UserService,
13
+ private jwtService: JwtService,
14
+ ) {
15
+ super();
16
+ }
17
+
18
+ async login(user: any, body: any = {}) {
19
+ const payload = {
20
+ userId: user._id,
21
+ name: user.name,
22
+ email: user.email,
23
+ roles: user.roles,
24
+ };
25
+
26
+ return {
27
+ access_token: this.jwtService.sign(payload, {
28
+ secret: 'secretKey',
29
+ expiresIn: '60d',
30
+ }),
31
+ user: {
32
+ _id: user._id,
33
+ name: user.name,
34
+ email: user.email,
35
+ roles: user.roles,
36
+ createdAt: user.createdAt,
37
+ updatedAt: user.updatedAt,
38
+ },
39
+ };
40
+ }
41
+
42
+ async validateUser(identifier: string, password: string): Promise<any> {
43
+ console.log(`IDENTIFIER =>`, identifier);
44
+ console.log(`password =>`, password);
45
+ const user = await this.userService.userRepository
46
+ .findOne({
47
+ $or: [{ email: identifier }, { username: identifier }],
48
+ })
49
+ .select('+password');
50
+ if (user && bcrypt.compareSync(password, user.password)) {
51
+ return user;
52
+ } else {
53
+ const userInLowerCase = await this.userService.userRepository
54
+ .findOne({
55
+ $or: [
56
+ { email: identifier.toLowerCase() },
57
+ { username: identifier.toLowerCase() },
58
+ ],
59
+ })
60
+ .select('+password');
61
+ if (
62
+ userInLowerCase &&
63
+ bcrypt.compareSync(password, userInLowerCase.password)
64
+ ) {
65
+ return userInLowerCase;
66
+ }
67
+ }
68
+ return null;
69
+ }
70
+
71
+ async validateByEmail(identifier: string): Promise<any> {
72
+ const user = await this.userService.userRepository.findOne({
73
+ $or: [{ email: identifier }, { username: identifier }],
74
+ });
75
+
76
+ if (user) {
77
+ const rUser = {
78
+ userId: user._id,
79
+ name: user.name,
80
+ username: user.username,
81
+ email: user.email,
82
+ roles: user.roles,
83
+ // iat: user.iat,
84
+ // exp: user.exp
85
+ };
86
+ return rUser;
87
+ } else {
88
+ const userInLowerCase = await this.userService.userRepository.findOne({
89
+ $or: [
90
+ { email: identifier.toLowerCase() },
91
+ { username: identifier.toLowerCase() },
92
+ ],
93
+ });
94
+ if (userInLowerCase) {
95
+ const rUser = {
96
+ userId: userInLowerCase._id,
97
+ name: userInLowerCase.name,
98
+ username: user.username,
99
+ email: userInLowerCase.email,
100
+ roles: userInLowerCase.roles,
101
+ };
102
+ return rUser;
103
+ }
104
+ }
105
+ return null;
106
+ }
107
+ }
src/modules/auth/jwt-auth.guard.ts ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import { Injectable, UnauthorizedException } from '@nestjs/common';
3
+ import { AuthGuard } from '@nestjs/passport';
4
+ import { AuthService } from './auth.service';
5
+
6
+ @Injectable()
7
+ export class JwtAuthGuard extends AuthGuard('jwt') {
8
+ handleRequest(err, user, info) {
9
+ // console.log( user, err, info )
10
+ // You can throw an exception based on either "info" or "err" arguments
11
+ // console.log(user, info, '##################JWT');
12
+ if (err || !user) {
13
+ // console.log('ERROR', err);
14
+ throw err || new UnauthorizedException();
15
+ }
16
+ return user;
17
+ }
18
+ }
src/modules/auth/jwt.strategy.ts ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { ExtractJwt } from 'passport-jwt';
2
+ import { PassportStrategy } from '@nestjs/passport';
3
+ import { Injectable } from '@nestjs/common';
4
+ import { Strategy } from 'passport-custom';
5
+ import { AuthService } from './auth.service';
6
+ import { jwtDecode } from 'jwt-decode';
7
+
8
+ @Injectable()
9
+ export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
10
+ constructor(private authService: AuthService) {
11
+ super();
12
+ }
13
+ async validate(req: Request): Promise<any> {
14
+ try {
15
+ const authHeader = String(req.headers['authorization'] || '');
16
+ if (authHeader.startsWith('Bearer ')) {
17
+ const token = authHeader.substring(7, authHeader.length);
18
+ const payload:any = jwtDecode(token) as any;
19
+ const user = this.authService.validateByEmail(payload.email)
20
+ return user ? user : false
21
+ }
22
+ else{
23
+ return false
24
+ }
25
+ } catch (error) {
26
+ return error
27
+ }
28
+
29
+ }
30
+ }
src/modules/auth/local-auth.guard.ts ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ import { Injectable } from '@nestjs/common';
2
+ import { AuthGuard } from '@nestjs/passport';
3
+
4
+ @Injectable()
5
+ export class LocalAuthGuard extends AuthGuard('local') {}
src/modules/auth/local.strategy.ts ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Strategy } from 'passport-local';
2
+ import { PassportStrategy } from '@nestjs/passport';
3
+ import {
4
+ HttpException,
5
+ HttpStatus,
6
+ Injectable,
7
+ UnauthorizedException,
8
+ } from '@nestjs/common';
9
+ import { AuthService } from './auth.service';
10
+
11
+ @Injectable()
12
+ export class LocalStrategy extends PassportStrategy(Strategy) {
13
+ constructor(private authService: AuthService) {
14
+ super({ usernameField: 'identifier' });
15
+ }
16
+
17
+ async validate(
18
+ identifier: string,
19
+ password: string,
20
+ isAdmin: boolean = false,
21
+ ): Promise<any> {
22
+ console.log(`IDENTIFIER =>`, identifier);
23
+
24
+ const user = await this.authService.validateUser(identifier, password);
25
+ if (!user) {
26
+ throw new UnauthorizedException('Incorrect username or password');
27
+ }
28
+
29
+ if ((user && user.deletedAt) || (user && user.isDeleted === true)) {
30
+ throw new HttpException(
31
+ 'Your account has been deleted',
32
+ HttpStatus.FORBIDDEN,
33
+ );
34
+ }
35
+ return user;
36
+ }
37
+ }
src/modules/database/database.module.ts ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Module } from '@nestjs/common';
2
+ import { databaseProviders } from './database.provider';
3
+ import { propertyProviders } from '../property/property.provider';
4
+ import { usersProviders } from '../user/user.provider';
5
+
6
+ @Module({
7
+ providers: [...databaseProviders, ...propertyProviders, ...usersProviders],
8
+ exports: [...databaseProviders, ...propertyProviders, ...usersProviders],
9
+ })
10
+ export class DatabaseModule {}
src/modules/database/database.provider.ts ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as mongoose from 'mongoose';
2
+ import { env } from 'process';
3
+
4
+ export const databaseProviders = [
5
+ {
6
+ provide: 'DATABASE_CONNECTION',
7
+ useFactory: (): Promise<typeof mongoose> =>
8
+ mongoose.connect(
9
+ 'mongodb+srv://rehmanwahlah248:[email protected]/property-listing?retryWrites=true&w=majority',
10
+ ),
11
+ },
12
+ ];
src/modules/property/property.controller.ts ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {
2
+ Body,
3
+ Controller,
4
+ Get,
5
+ HttpStatus,
6
+ Post,
7
+ Query,
8
+ Req,
9
+ Res,
10
+ UseGuards,
11
+ } from '@nestjs/common';
12
+ import { Response } from 'express';
13
+ import { CommonServices } from '../shared/common.service';
14
+ import { PropertyService } from './property.service';
15
+
16
+ @Controller('property')
17
+ export class PropertyController extends CommonServices {
18
+ constructor(private readonly propertyService: PropertyService) {
19
+ super();
20
+ }
21
+
22
+ @Get('')
23
+ async getPropertListings(@Res() res: Response, @Req() req): Promise<any> {
24
+ try {
25
+ const response = await this.propertyService.sharedFind({});
26
+ return this.sendResponse(
27
+ this.messages.Success,
28
+ response ?? 'NOT_FOUND',
29
+ HttpStatus.OK,
30
+ res,
31
+ );
32
+ } catch (error) {
33
+ return this.sendResponse(
34
+ 'Internal server Error',
35
+ {},
36
+ HttpStatus.INTERNAL_SERVER_ERROR,
37
+ res,
38
+ );
39
+ }
40
+ }
41
+
42
+ /**
43
+ *
44
+ * @param query
45
+ * @param res
46
+ * @param req
47
+ */
48
+ @Get('/listings/dashboard')
49
+ async getDashboardLisings(@Res() res, @Req() req) {
50
+ try {
51
+ const listings = await this.propertyService.propertyRepository
52
+ .find({})
53
+ .sort({ _id: -1 })
54
+ .limit(20);
55
+
56
+ this.sendResponse(this.messages.Success, listings, HttpStatus.OK, res);
57
+ } catch (error) {
58
+ console.error('error', error);
59
+ this.sendResponse(
60
+ this.messages.Error,
61
+ null,
62
+ HttpStatus.INTERNAL_SERVER_ERROR,
63
+ res,
64
+ );
65
+ }
66
+ }
67
+
68
+ /**
69
+ *
70
+ * @param query
71
+ * @param res
72
+ * @param req
73
+ */
74
+ @Get('/listings')
75
+ async getDashboardActiveUsers(@Query() query, @Res() res, @Req() req) {
76
+ try {
77
+ const page = Number(query.page);
78
+ const resPerPage = query.resPerPage ? Number(query.resPerPage) : 20;
79
+ const search = query.search || ''; // Default to empty search if not provided
80
+
81
+ console.log(`search =>`, query);
82
+
83
+ const listings = await this.propertyService.propertyLisitng(
84
+ page,
85
+ resPerPage,
86
+ search,
87
+ );
88
+
89
+ this.sendResponse(this.messages.Success, listings, HttpStatus.OK, res);
90
+ } catch (error) {
91
+ console.error('error', error);
92
+ this.sendResponse(
93
+ this.messages.Error,
94
+ null,
95
+ HttpStatus.INTERNAL_SERVER_ERROR,
96
+ res,
97
+ );
98
+ }
99
+ }
100
+ }
src/modules/property/property.module.ts ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Module } from '@nestjs/common';
2
+ import { PropertyController } from './property.controller';
3
+ import { PropertyService } from './property.service';
4
+ import { DatabaseModule } from '../database/database.module';
5
+
6
+ @Module({
7
+ imports: [DatabaseModule],
8
+ controllers: [PropertyController],
9
+ providers: [PropertyService],
10
+ exports: [PropertyService],
11
+ })
12
+ export class PropertyModule {}
src/modules/property/property.provider.ts ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Connection } from 'mongoose';
2
+ import { PROPERTIE, PROPERTY_REPOSITORY } from 'src/constants';
3
+ import { PropertySchema } from './property.schema';
4
+
5
+ export const propertyProviders = [
6
+ {
7
+ provide: PROPERTY_REPOSITORY,
8
+ useFactory: (connection: Connection) =>
9
+ connection.model(PROPERTIE, PropertySchema),
10
+ inject: ['DATABASE_CONNECTION'],
11
+ },
12
+ ];
src/modules/property/property.schema.ts ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as mongoose from 'mongoose';
2
+ import { Document } from 'mongoose';
3
+
4
+ export interface IPropertyDocument extends Document {
5
+ title?: string;
6
+ price?: string;
7
+ id?: string;
8
+ imgs?: Array<[]>;
9
+ desc?: string;
10
+ features?: object;
11
+ thumbnail_summary?: string;
12
+ listing_url?: string;
13
+ createdAt?: Date;
14
+ updatedAt?: Date;
15
+ }
16
+
17
+ const PropertySchema = new mongoose.Schema<IPropertyDocument>(
18
+ {
19
+ title: { type: String },
20
+ price: { type: String },
21
+ id: { type: String },
22
+ desc: { type: String, unique: true },
23
+ features: { type: Object },
24
+ listing_url: { type: String },
25
+ imgs: [],
26
+ createdAt: { type: Date, default: Date.now },
27
+ updatedAt: { type: Date, default: Date.now },
28
+ },
29
+ {
30
+ toJSON: { versionKey: false },
31
+ },
32
+ );
33
+
34
+ export { PropertySchema };
src/modules/property/property.service.ts ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Inject, Injectable } from '@nestjs/common';
2
+ import { Model, Types } from 'mongoose';
3
+ import { sharedCrudService } from '../shared/sharedCrud.services';
4
+ import { PROPERTY_REPOSITORY } from 'src/constants';
5
+ import { IPropertyDocument } from './property.schema';
6
+
7
+ @Injectable()
8
+ export class PropertyService extends sharedCrudService {
9
+ constructor(
10
+ @Inject(PROPERTY_REPOSITORY)
11
+ readonly propertyRepository: Model<IPropertyDocument>,
12
+ ) {
13
+ super(propertyRepository);
14
+ }
15
+
16
+ async propertyLisitng(
17
+ page: number,
18
+ resPerPage: number,
19
+ search: string,
20
+ ): Promise<any> {
21
+ const query = [];
22
+ query.push({ id: { $exists: true } });
23
+
24
+ if (search) query.push({ title: { $regex: search, $options: 'i' } });
25
+
26
+ const [listings, tLisitngsCount] = await Promise.all([
27
+ this.propertyRepository
28
+ .find({ $and: [...query] })
29
+ .sort({ createdAt: -1 })
30
+ .skip(resPerPage * (page - 1))
31
+ .limit(resPerPage)
32
+ .exec(),
33
+ this.propertyRepository.countDocuments({ $and: [...query] }).exec(),
34
+ ]);
35
+
36
+ return {
37
+ listings,
38
+ current_page: page,
39
+ pages: Math.ceil(tLisitngsCount / resPerPage),
40
+ total_listings: tLisitngsCount,
41
+ per_page: resPerPage,
42
+ };
43
+ }
44
+ }
src/modules/shared/common.service.ts ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { en } from 'src/locales/en';
2
+ import { I18nResolver } from 'i18n-ts';
3
+ import { Inject, Injectable } from '@nestjs/common';
4
+ import * as constants from '../../constants'
5
+
6
+ const i18n = {
7
+ en: en,
8
+ default: en,
9
+ };
10
+
11
+ @Injectable()
12
+ export class CommonServices{
13
+ public messages = new I18nResolver(i18n, 'en').translation;
14
+ public constants = constants;
15
+ constructor() {
16
+ }
17
+
18
+ /**
19
+ * name
20
+ */
21
+ public sendResponse = (mesage, data, status, res) => {
22
+ return res.status(status).json({
23
+ message: mesage,
24
+ data: data,
25
+ });
26
+ };
27
+ }
src/modules/shared/sharedCrud.services.ts ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Injectable } from '@nestjs/common';
2
+
3
+ @Injectable()
4
+ export class sharedCrudService {
5
+ private service;
6
+ constructor(private serviceObj) {
7
+ // super();
8
+ this.service = serviceObj;
9
+ }
10
+ sharedCreate = (body) => {
11
+ return this.service.create(body);
12
+ };
13
+ sharedUpdate = (clause, body) => {
14
+ return this.service.updateOne(clause, body);
15
+ };
16
+ sharedFindOne = (clause) => {
17
+ return this.service.findOne(clause);
18
+ };
19
+ sharedFindOneAndUpdate = (clause, body, options) => {
20
+ return this.service.findOneAndUpdate(clause, body, options);
21
+ };
22
+ sharedFind = (clause) => {
23
+ return this.service.find(clause);
24
+ };
25
+ sharedDelete = (clause) => {
26
+ return this.service.deleteOne(clause);
27
+ };
28
+ }
src/modules/user/user.controller.ts ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {
2
+ Body,
3
+ Controller,
4
+ Get,
5
+ HttpStatus,
6
+ Post,
7
+ Query,
8
+ Req,
9
+ Res,
10
+ UseGuards,
11
+ } from '@nestjs/common';
12
+ import { UserService } from './user.service';
13
+ import { Response } from 'express';
14
+ import { CommonServices } from '../shared/common.service';
15
+ import { JwtAuthGuard } from '../auth/jwt-auth.guard'
16
+
17
+
18
+ @Controller('user')
19
+ export class UserController extends CommonServices {
20
+ constructor(
21
+ private readonly userService: UserService,
22
+ ) {
23
+ super();
24
+ }
25
+
26
+ @Get('')
27
+ @UseGuards(JwtAuthGuard)
28
+ async getUserDetails(@Res() res: Response, @Req() req): Promise<any> {
29
+ try {
30
+ const response = await this.userService.userRepository.findById(
31
+ req.user.userId,
32
+ );
33
+
34
+ return this.sendResponse(
35
+ this.messages.Success,
36
+ response ?? 'NOT_FOUND',
37
+ HttpStatus.OK,
38
+ res,
39
+ );
40
+ } catch (error) {
41
+ return this.sendResponse(
42
+ 'Internal server Error',
43
+ {},
44
+ HttpStatus.INTERNAL_SERVER_ERROR,
45
+ res,
46
+ );
47
+ }
48
+ }
49
+ }
src/modules/user/user.dto.ts ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {
2
+ IsEmail,
3
+ IsNotEmpty,
4
+ IsOptional,
5
+ IsString,
6
+ ValidateNested,
7
+ } from 'class-validator';
8
+ export class UpdateProfileDto {
9
+ @IsOptional()
10
+ firstName: string;
11
+
12
+ @IsOptional()
13
+ lastName: string;
14
+
15
+ @IsOptional()
16
+ username: string;
17
+
18
+ @IsOptional()
19
+ email: string;
20
+
21
+ avatar: any;
22
+ ats: any;
23
+ }
24
+
25
+ export class updatePasswordDto {
26
+ @IsNotEmpty()
27
+ password: string;
28
+
29
+ @IsNotEmpty()
30
+ newPassword: string;
31
+
32
+ @IsNotEmpty()
33
+ confirmPassword: string;
34
+ }
35
+
36
+ export class addRemoveFriendDto {
37
+ @IsNotEmpty()
38
+ userId: string;
39
+
40
+ @IsNotEmpty()
41
+ type: string;
42
+ }
43
+ export class validateEmailDto {
44
+ @IsString()
45
+ identifier: string;
46
+ }
47
+ export class NewsletterDto {
48
+ @IsString()
49
+ email: string;
50
+ }
51
+ export class validateEmailRegDto {
52
+ @IsString()
53
+ @IsEmail()
54
+ email: string;
55
+ }
src/modules/user/user.module.ts ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Module } from '@nestjs/common';
2
+ import { UserController } from './user.controller';
3
+ import { UserService } from './user.service';
4
+ import { DatabaseModule } from '../database/database.module';
5
+ import { AuthService } from '../auth/auth.service';
6
+ import { JwtService } from '@nestjs/jwt';
7
+ @Module({
8
+ imports: [DatabaseModule],
9
+ controllers: [UserController],
10
+ providers: [UserService, AuthService, JwtService],
11
+ exports: [UserService, AuthService, JwtService],
12
+ })
13
+ export class UserModule {}
src/modules/user/user.provider.ts ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Connection } from 'mongoose';
2
+ import { USERS, USER_REPOSITORY } from 'src/constants';
3
+ import { UserSchema } from './user.schema';
4
+
5
+ export const usersProviders = [
6
+ {
7
+ provide: USER_REPOSITORY,
8
+ useFactory: (connection: Connection) => connection.model(USERS, UserSchema),
9
+ inject: ['DATABASE_CONNECTION'],
10
+ },
11
+ ];
src/modules/user/user.schema.ts ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as mongoose from 'mongoose';
2
+ import { Document } from 'mongoose';
3
+ import { USERS } from 'src/constants';
4
+
5
+ export interface IUserDocument extends Document {
6
+ name?: string;
7
+ username?: string;
8
+ email?: string;
9
+ avatar?: string;
10
+ isActive?: boolean;
11
+ isDeleted: boolean;
12
+ createdAt?: Date;
13
+ updatedAt?: Date;
14
+ deletedAt?: Date;
15
+ roles?: Array<string>;
16
+ password?: string;
17
+ session_id?: number;
18
+ login_location?: string;
19
+ preferred_location?: string;
20
+ preferred_listing_type?: string;
21
+ property_id?: string;
22
+ page_visit_duration?: number;
23
+ carousel_button_click_result_page?: number;
24
+ next_image_clicks_listing_page?: number;
25
+ read_more_click_result_page?: number;
26
+ read_more_click_listing_page?: number;
27
+ clicked_more_pictures?: number;
28
+ click_rate?: number;
29
+ bounce?: number;
30
+ title?: string;
31
+ price?: string;
32
+ bedrooms_?: string;
33
+ bathrooms?: string;
34
+ living_space_sqm?: string;
35
+ pool_?: number;
36
+ }
37
+
38
+ const UserSchema = new mongoose.Schema<IUserDocument>(
39
+ {
40
+ name: { type: String },
41
+ username: { type: String },
42
+ email: { type: String },
43
+ avatar: { type: String },
44
+ isActive: { type: Boolean, default: true },
45
+ isDeleted: { type: Boolean, default: false },
46
+ roles: [{ type: String, required: true, default: 'user' }],
47
+ password: { type: String, required: false },
48
+ // New fields added from IUserDocument
49
+ session_id: { type: Number },
50
+ login_location: { type: String },
51
+ preferred_location: { type: String },
52
+ preferred_listing_type: { type: String },
53
+ property_id: { type: String },
54
+ page_visit_duration: { type: Number, default: 0 },
55
+ carousel_button_click_result_page: { type: Number, default: 0 },
56
+ next_image_clicks_listing_page: { type: Number, default: 0 },
57
+ read_more_click_result_page: { type: Number, default: 0 },
58
+ read_more_click_listing_page: { type: Number, default: 0 },
59
+ clicked_more_pictures: { type: Number, default: 0 },
60
+ click_rate: { type: Number, default: 0 },
61
+ bounce: { type: Number, default: 0 },
62
+ title: { type: String },
63
+ price: { type: String },
64
+ bedrooms_: { type: String },
65
+ bathrooms: { type: String },
66
+ living_space_sqm: { type: String },
67
+ pool_: { type: Number },
68
+
69
+ createdAt: { type: Date, default: Date.now },
70
+ updatedAt: { type: Date, default: Date.now },
71
+ deletedAt: { type: Date },
72
+ },
73
+ {
74
+ toJSON: { versionKey: false },
75
+ },
76
+ );
77
+
78
+ export { UserSchema };
src/modules/user/user.service.ts ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Inject, Injectable } from '@nestjs/common';
2
+ import { Model, Types } from 'mongoose';
3
+ import { USER_REPOSITORY } from 'src/constants';
4
+ import { IUserDocument } from './user.schema';
5
+ import { sharedCrudService } from '../shared/sharedCrud.services';
6
+
7
+ interface UserDocument extends IUserDocument {
8
+ _id: Types.ObjectId;
9
+ }
10
+
11
+ @Injectable()
12
+ export class UserService extends sharedCrudService {
13
+ constructor(
14
+ @Inject(USER_REPOSITORY) readonly userRepository: Model<IUserDocument>,
15
+ ) {
16
+ super(userRepository);
17
+ }
18
+
19
+ async getUserData(reqUser: any) {
20
+ const user = await this.userRepository.findById({
21
+ _id: reqUser._id,
22
+ });
23
+ return user;
24
+ }
25
+ }
test/app.e2e-spec.ts ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Test, TestingModule } from '@nestjs/testing';
2
+ import { INestApplication } from '@nestjs/common';
3
+ import * as request from 'supertest';
4
+ import { AppModule } from './../src/app.module';
5
+
6
+ describe('AppController (e2e)', () => {
7
+ let app: INestApplication;
8
+
9
+ beforeEach(async () => {
10
+ const moduleFixture: TestingModule = await Test.createTestingModule({
11
+ imports: [AppModule],
12
+ }).compile();
13
+
14
+ app = moduleFixture.createNestApplication();
15
+ await app.init();
16
+ });
17
+
18
+ it('/ (GET)', () => {
19
+ return request(app.getHttpServer())
20
+ .get('/')
21
+ .expect(200)
22
+ .expect('Hello World!');
23
+ });
24
+ });
test/jest-e2e.json ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "moduleFileExtensions": ["js", "json", "ts"],
3
+ "rootDir": ".",
4
+ "testEnvironment": "node",
5
+ "testRegex": ".e2e-spec.ts$",
6
+ "transform": {
7
+ "^.+\\.(t|j)s$": "ts-jest"
8
+ }
9
+ }
tsconfig.build.json ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
4
+ }
tsconfig.json ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "compilerOptions": {
3
+ "module": "commonjs",
4
+ "declaration": true,
5
+ "removeComments": true,
6
+ "emitDecoratorMetadata": true,
7
+ "experimentalDecorators": true,
8
+ "allowSyntheticDefaultImports": true,
9
+ "target": "ES2021",
10
+ "sourceMap": true,
11
+ "outDir": "./dist",
12
+ "baseUrl": "./",
13
+ "incremental": true,
14
+ "skipLibCheck": true,
15
+ "strictNullChecks": false,
16
+ "noImplicitAny": false,
17
+ "strictBindCallApply": false,
18
+ "forceConsistentCasingInFileNames": false,
19
+ "noFallthroughCasesInSwitch": false
20
+ }
21
+ }