crud apis and soft delete

This commit is contained in:
harshithnrao 2025-02-25 12:53:59 +05:30
commit abe3b4744e
78 changed files with 23574 additions and 0 deletions

8
.env Normal file
View File

@ -0,0 +1,8 @@
POSTGRES_HOST=127.0.0.1
POSTGRES_PORT=5432
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DATABASE=wastecare
PORT=3000
MODE=DEV
RUN_MIGRATIONS=false

24
.eslintrc.js Normal file
View File

@ -0,0 +1,24 @@
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.json',
tsconfigRootDir: __dirname,
sourceType: 'module',
},
plugins: ['@typescript-eslint/eslint-plugin'],
extends: [
'plugin:@typescript-eslint/recommended',
],
root: true,
env: {
node: true,
jest: true,
},
ignorePatterns: ['.eslintrc.js'],
rules: {
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
},
};

36
.gitignore vendored Normal file
View File

@ -0,0 +1,36 @@
# compiled output
/dist
/node_modules
/uploads/*
# Logs
logs
*.log
npm-debug.log*
pnpm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# OS
.DS_Store
# Tests
/coverage
/.nyc_output
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json

1
Insomnia_2024-01-21.json Normal file

File diff suppressed because one or more lines are too long

73
README.md Normal file
View File

@ -0,0 +1,73 @@
<p align="center">
<a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo-small.svg" width="200" alt="Nest Logo" /></a>
</p>
[circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456
[circleci-url]: https://circleci.com/gh/nestjs/nest
<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>
<p align="center">
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a>
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/l/@nestjs/core.svg" alt="Package License" /></a>
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/dm/@nestjs/common.svg" alt="NPM Downloads" /></a>
<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>
<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>
<a href="https://discord.gg/G7Qnnhy" target="_blank"><img src="https://img.shields.io/badge/discord-online-brightgreen.svg" alt="Discord"/></a>
<a href="https://opencollective.com/nest#backer" target="_blank"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a>
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a>
<a href="https://paypal.me/kamilmysliwiec" target="_blank"><img src="https://img.shields.io/badge/Donate-PayPal-ff3f59.svg"/></a>
<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>
<a href="https://twitter.com/nestframework" target="_blank"><img src="https://img.shields.io/twitter/follow/nestframework.svg?style=social&label=Follow"></a>
</p>
<!--[![Backers on Open Collective](https://opencollective.com/nest/backers/badge.svg)](https://opencollective.com/nest#backer)
[![Sponsors on Open Collective](https://opencollective.com/nest/sponsors/badge.svg)](https://opencollective.com/nest#sponsor)-->
## Description
[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository.
## Installation
```bash
$ npm install
```
## Running the app
```bash
# development
$ npm run start
# watch mode
$ npm run start:dev
# production mode
$ npm run start:prod
```
## Test
```bash
# unit tests
$ npm run test
# e2e tests
$ npm run test:e2e
# test coverage
$ npm run test:cov
```
## Support
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).
## Stay in touch
- Author - [Kamil Myśliwiec](https://kamilmysliwiec.com)
- Website - [https://nestjs.com](https://nestjs.com/)
- Twitter - [@nestframework](https://twitter.com/nestframework)
## License
Nest is [MIT licensed](LICENSE).

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,90 @@
CREATE TABLE "actions_ref" (
"id" BIGSERIAL PRIMARY KEY,
"appCode" TEXT,
"actionCode" TEXT,
"actionName" TEXT,
"validFrom" DATE,
"validTo" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createdBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);
CREATE TABLE "crud_config_info" (
"id" BIGSERIAL PRIMARY KEY,
"endPtNum" NUMERIC,
"opsTypeName" TEXT,
"sqlQueryText" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdBy" TEXT,
"modifiedBy" TEXT,
"status" TEXT,
"version" NUMERIC,
"deletedAt" DATE,
"createdAt" DATE,
"updatedAt" DATE
);
CREATE TABLE "policies_ref" (
"id" BIGSERIAL PRIMARY KEY,
"appCode" TEXT,
"roleCode" TEXT,
"resourceCode" TEXT,
"actionCode" TEXT,
"canAllow" BOOLEAN,
"priority" NUMERIC,
"validFrom" DATE,
"validTo" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createdBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);
CREATE TABLE "resources_ref" (
"id" BIGSERIAL PRIMARY KEY,
"appCode" TEXT,
"resourceCode" TEXT,
"resourceName" TEXT,
"validFrom" DATE,
"validTo" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createdBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);
CREATE TABLE "rules_ref" (
"id" BIGSERIAL PRIMARY KEY,
"ruleCode" TEXT,
"ruleName" TEXT,
"ruleType" TEXT,
"ruleDesc" TEXT,
"ruleText" TEXT,
"validFrom" DATE,
"validTo" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createdBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);
CREATE TABLE "rules_details_ref" (
"id" BIGSERIAL PRIMARY KEY,
"ruleCode" TEXT,
"ruleAttrName" TEXT,
"ruleAttrText" TEXT,
"validFrom" DATE,
"validTo" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createdBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);

View File

@ -0,0 +1,283 @@
CREATE TABLE public.actions_ref (
id bigserial NOT NULL,
"appCode" text,
"actionCode" text,
"actionName" text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.apps_ref (
id bigserial NOT NULL,
"appCode" text,
"appName" text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.companies (
id bigserial NOT NULL,
"companyCode" text,
"companyName" text,
address text,
gst text,
status text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.company_details (
id bigserial NOT NULL,
"companyId" numeric,
"companyCode" text,
"addlDataType" text,
"addlDataName" text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.crud_config_info (
id bigserial NOT NULL,
"endPtNm" text,
"opsTypeName" text,
"sqlQueryText" text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.item_category_ref (
id bigserial NOT NULL,
"categoryName" text,
"categoryCode" text,
"categoryDescription" text,
"parentCode" text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.items_ref (
id bigserial NOT NULL,
"itemCode" text,
"itemName" text,
"itemCategoryCode" text,
"itemDesc" text,
"parentCode" text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.policies_ref (
id bigserial NOT NULL,
"appCode" text,
"roleCode" text,
"resourceCode" text,
"actionCode" text,
"canAllow" boolean,
priority boolean,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.resources_ref (
id bigserial NOT NULL,
"appCode" text,
"resourceCode" text,
"resourceName" text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.roles_ref (
id bigserial NOT NULL,
"appCode" text,
"roleCode" text,
"roleName" text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.user_additional_details (
id bigserial NOT NULL,
"userId" numeric,
"addlDataType" text,
"addlDataName" text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.users (
id bigserial NOT NULL,
email text,
password text,
name text,
"userTypeCode" text,
"primaryRole" text,
"companyCode" text,
status text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.master_config_category_ref (
id bigserial NOT NULL,
"categoryName" text,
"categoryCode" text,
"categoryDescription" text,
"categoryType" text,
"parentCode" text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.master_config_ref (
id bigserial NOT NULL,
"configCode" text,
"configName" text,
"configCategoryCode" text,
"configDesc" text,
"parentCode" text,
"configType" text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.master_config_mapping (
id bigserial NOT NULL,
"configCode" text,
"companyCode" text,
"status" text,
"dispSerialNumber" text,
"defaultValue" text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.config_transcations (
id bigserial NOT NULL,
"configCode" text,
"companyCode" text,
"itemCategoryCode" text,
"itemCode" text,
"status" text,
"value" text,
"fileUrl" text,
"weight" numeric,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
);
CREATE TABLE public.config_logs (
id bigserial NOT NULL,
"tableName" text,
"prevValue" text,
"currValue" text,
"validFrom" date,
"validTill" date,
"createdAt" date,
"updatedAt" date,
"createBy" text,
"modifiedBy" text,
"deletedAt" date,
version numeric
)

10
nest-cli.json Normal file
View File

@ -0,0 +1,10 @@
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"deleteOutDir": true,
"assets": ["mail/templates/**/*"],
"watchAssets": true
}
}

11
nodemon.json Normal file
View File

@ -0,0 +1,11 @@
{
"watch": [
"src"
],
"ext": "ts",
"ignore": [
"src/**/*.spec.ts"
],
"exec": "node --inspect=127.0.0.1:9223 -r ts-node/register -- src/main.ts",
"env": {}
}

20337
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

88
package.json Normal file
View File

@ -0,0 +1,88 @@
{
"name": "abnandan-skeleton-be",
"version": "0.0.1",
"description": "",
"author": "",
"private": true,
"license": "UNLICENSED",
"scripts": {
"build": "node script-util.js config.local.json config.json && nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "node script-util.js config.local.json config.json && nest start",
"start:local": "node script-util.js config.local.json config.json && nest start --watch",
"start:debug": "node script-util.js config.local.json config.json && nest start --debug --watch",
"start:prod": "node dist/main",
"build:dev": "node script-util.js config.dev.json config.json && nest build && cp package.json dist/package.json && cp -r config dist/",
"build:prod": "node script-util.js config.prod.json config.json && nest build && cp package.json dist/package.json && cp -r config dist/",
"build:test": "node script-util.js config.test.json config.json && nest build && cp package.json dist/package.json && cp -r config dist/",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"test": "jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@nestjs-modules/mailer": "^1.10.3",
"@nestjs/common": "^10.0.0",
"@nestjs/config": "^3.1.1",
"@nestjs/core": "^10.0.0",
"@nestjs/platform-express": "^10.0.0",
"@nestjs/typeorm": "^10.0.1",
"dotenv": "^16.3.1",
"handlebars": "^4.7.8",
"moment": "^2.30.1",
"nodemailer": "^6.9.9",
"otp-generator": "^4.0.1",
"pg": "^8.11.3",
"reflect-metadata": "^0.1.14",
"rxjs": "^7.8.1",
"sequelize": "^6.35.2",
"sequelize-typescript": "^2.1.6",
"typeorm": "^0.3.17"
},
"devDependencies": {
"@nestjs/cli": "^10.0.0",
"@nestjs/schematics": "^10.0.0",
"@nestjs/testing": "^10.0.0",
"@types/express": "^4.17.17",
"@types/jest": "^29.5.2",
"@types/multer": "^1.4.11",
"@types/node": "^20.10.6",
"@types/nodemailer": "^6.4.14",
"@types/supertest": "^2.0.12",
"@types/validator": "^13.11.7",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"eslint": "^8.42.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.0",
"jest": "^29.5.0",
"nodemon": "^3.0.2",
"prettier": "^3.0.0",
"source-map-support": "^0.5.21",
"supertest": "^6.3.3",
"ts-jest": "^29.1.0",
"ts-loader": "^9.4.3",
"ts-node": "^10.9.2",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.1.3"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node"
}
}

11
script-util.js Normal file
View File

@ -0,0 +1,11 @@
/* eslint-disable @typescript-eslint/no-var-requires */
// Import the required modules
const fs = require('fs');
// Get the source and destination file paths from the command-line arguments
const sourcePath = `src/app-config/${process.argv[2]}`;
const destinationPath = `src/app-config/${process.argv[3]}`;
// Read the source file
fs.writeFileSync(destinationPath, fs.readFileSync(sourcePath));

View File

@ -0,0 +1,106 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { ActionsService } from './actions.service';
import { Response } from 'express';
import { GenericResponse } from '../common/GenericResponse.model';
import Actions from './actions.entity';
@Controller('actions')
export class ActionsController {
constructor(private actionsService: ActionsService) {}
@Get("/all")
async getAllActionss(@Res() res: Response) {
const response = await this.actionsService.findAll() || [];
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Get(':id')
async findById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.actionsService.findByPk(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post('/filter')
async filter(@Body() actions: Actions, @Res() res: Response) {
if(!actions) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.actionsService.filter(actions) || [];
const httpResponse = new GenericResponse(null, response)
res.status(200).send(httpResponse);
}
@Post()
async insert(@Body() actions: Actions, @Res() res: Response) {
if(!actions) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
delete actions.id;
const response = await this.actionsService.upsert(actions, true);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Put()
async update(@Body() actions: Actions, @Res() res: Response) {
if(!actions || !actions.id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.actionsService.upsert(actions, false);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Delete(':id')
async deleteById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.actionsService.remove(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
}

View File

@ -0,0 +1,40 @@
import { Table, Column, Model, Default, DataType } from 'sequelize-typescript';
@Table({ tableName: 'actions_ref' , paranoid : true})
export default class Actions extends Model {
@Column(DataType.TEXT)
appCode: string;
@Column(DataType.TEXT)
actionCode: string;
@Column(DataType.TEXT)
actionName: string;
@Default(new Date())
@Column(DataType.DATEONLY)
validFrom: Date;
@Default(new Date("2070-12-31"))
@Column(DataType.DATEONLY)
validTo: Date;
@Column(DataType.DATEONLY)
createdAt: Date;
@Column(DataType.DATEONLY)
updatedAt: Date;
@Column(DataType.TEXT)
createdBy: string;
@Column(DataType.TEXT)
modifiedBy: string;
@Column(DataType.DATEONLY)
deletedAt: Date;
@Column(DataType.NUMBER)
version: number;
}

View File

@ -0,0 +1,10 @@
import { Module } from '@nestjs/common';
import { ActionsController } from './actions.controller';
import { ActionsService } from './actions.service';
@Module({
providers: [ActionsService],
controllers: [ActionsController],
imports: []
})
export class ActionsModule { }

View File

@ -0,0 +1,41 @@
import { Injectable } from '@nestjs/common';
import Actions from './actions.entity';
@Injectable()
export class ActionsService {
constructor() { }
async findAll(): Promise<{ rows: Actions[], count: number }> {
return Actions.findAndCountAll();
}
findByPk(id: number): Promise<Actions> {
return Actions.findByPk(id,)
}
findOne(actions: Actions): Promise<Actions> {
return Actions.findOne({ where: actions as any, })
}
filter(actions: Actions): Promise<Actions[]> {
return Actions.findAll({ where: actions as any, })
}
async remove(id: number): Promise<number> {
return Actions.destroy({ where: { id: id } });
}
async upsert(actions: Actions, insertIfNotFound: boolean): Promise<Actions | [affectedCount: number]> {
if (actions.id) {
const existingActions = await this.findByPk(actions.id);
if (existingActions) {
return Actions.update(actions, { where: { id: actions.id } });
}
}
if (insertIfNotFound) {
return Actions.create(actions as any)
}
}
}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AppConfigController } from './app-config.controller';
describe('AppConfigController', () => {
let controller: AppConfigController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [AppConfigController],
}).compile();
controller = module.get<AppConfigController>(AppConfigController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});

View File

@ -0,0 +1,74 @@
import { Controller, Get, Post, Query, Req, Res } from '@nestjs/common';
import { getFile, updateFile } from './file.util';
import { Request, Response } from 'express';
import { Utility } from 'src/common/Utility';
@Controller('app-config')
export class AppConfigController {
@Get('/')
async get(@Req() req: Request, @Query() query, @Res() res: Response) {
console.log('Inside Config Controller GET', query);
const filePath = (query.path) ? `${Utility.fileConfig.configPath}/${query.path}` : `${Utility.fileConfig.configPath}`;
const response = await getFile(filePath, 'UTF-8');
return res.status(200).send(response);
}
@Post('/')
async post(@Req() req: Request, @Res() res: Response) {
const filePath = `${Utility.fileConfig.configPath}`;
const fileName = (req.body && req.body.fileName) ? req.body.fileName : null;
let data = (req.body && req.body.data) ? req.body.data : null;
let resultSet = {};
console.log('Inside Config Controller Post');
console.log(`File Path ${filePath}`);
console.log(`File Name ${fileName}`);
console.log(`File Data ${data}`);
if (!filePath || !fileName || !data) {
resultSet = {
exception: true,
exceptionMessage: 'Invalid Params',
exceptionSeverity: 'high'
}
return res.status(400).send(resultSet);
}
if(typeof data === 'object') {
data = JSON.stringify(data);
}
const response = await updateFile(filePath,fileName,data);
resultSet['result'] = response;
return res.status(200).send(resultSet);
}
}
/*
location /assessment {
rewrite ^/assessment/(.*)$ /$1 break;
proxy_pass http://localhost:3001;
proxy_redirect off;
proxy_set_header Host $host;
}
location /content {
rewrite ^/content/(.*)$ /$1 break;
proxy_pass http://localhost:3002;
proxy_redirect off;
proxy_set_header Host $host;
}
location /dataservice {
rewrite ^/dataservice/(.*)$ /$1 break;
proxy_pass http://localhost:3003;
proxy_redirect off;
proxy_set_header Host $host;
}
location /payments {
rewrite ^/payments/(.*)$ /$1 break;
proxy_pass http://localhost:3004;
proxy_redirect off;
proxy_set_header Host $host;
}
location /users {
rewrite ^/users/(.*)$ /$1 break;
proxy_pass http://localhost:3005;
proxy_redirect off;
proxy_set_header Host $host;
}
*/

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AppConfigService } from './app-config.service';
describe('AppConfigService', () => {
let service: AppConfigService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [AppConfigService],
}).compile();
service = module.get<AppConfigService>(AppConfigService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

View File

@ -0,0 +1,44 @@
import { Injectable } from '@nestjs/common';
import * as configMaster from './config.json';
@Injectable()
export class AppConfigService {
defaultEnv = 'local';
constructor() {
}
private getValue(key: string, throwOnMissing = true): any {
const value = configMaster[this.defaultEnv].dbConfig[key];
if (!value && throwOnMissing) {
throw new Error(`config error - missing env.${key}`);
}
return value;
}
public ensureValues(keys: string[]) {
keys.forEach(k => this.getValue(k, true));
return this;
}
public getPort() {
return this.getValue('PORT', true);
}
public isProduction() {
const mode = this.getValue('MODE', false);
return mode != 'DEV';
}
getDbConfig() {
return configMaster[this.defaultEnv].dbConfig;
}
initializeFileSystem() {
return configMaster[this.defaultEnv].fileConfig;
}
getMailConfig() {
return configMaster[this.defaultEnv].mailConfig;
}
}

View File

@ -0,0 +1,34 @@
{
"local": {
"appConfig": {
"port": 3003
},
"dbConfig": {
"host": "localhost",
"port": 5432,
"user": "postgres",
"password": "postgres",
"database": "epr",
"MODE": "DEV",
"loggerEnabled": true
},
"fileConfig": {
"storagePath": "/opt/www/wastecare-uploads/dev",
"configPath": "/opt/wastecare/config/dev"
},
"mailConfig": {
"transport": {
"host": "smtppro.zoho.in",
"secure": true,
"port": 465,
"auth": {
"user": "admin@wct.co.in",
"pass": "Wastecare@123"
}
},
"defaults": {
"from": "\"No Reply\" <admin@wct.co.in>"
}
}
}
}

View File

@ -0,0 +1,34 @@
{
"local": {
"appConfig": {
"port": 3003
},
"dbConfig": {
"host": "localhost",
"port": 5432,
"user": "postgres",
"password": "postgres",
"database": "remedify-dataservice-local",
"MODE": "DEV",
"loggerEnabled": true
},
"fileConfig": {
"storagePath": "./uploads",
"configPath": "./config"
},
"mailConfig": {
"transport": {
"host": "smtppro.zoho.in",
"secure": true,
"port": 465,
"auth": {
"user": "admin@wct.co.in",
"pass": "Wastecare@123"
}
},
"defaults": {
"from": "\"No Reply\" <admin@wct.co.in>"
}
}
}
}

View File

@ -0,0 +1,34 @@
{
"local": {
"appConfig": {
"port": 3003
},
"dbConfig": {
"host": "localhost",
"port": 5432,
"user": "postgres",
"password": "postgres",
"database": "remedify-dataservice-local",
"MODE": "DEV",
"loggerEnabled": true
},
"fileConfig": {
"storagePath": "./uploads",
"configPath": "./config"
},
"mailConfig": {
"transport": {
"host": "smtppro.zoho.in",
"secure": true,
"port": 465,
"auth": {
"user": "admin@wct.co.in",
"pass": "Wastecare@123"
}
},
"defaults": {
"from": "\"No Reply\" <admin@wct.co.in>"
}
}
}
}

View File

@ -0,0 +1,34 @@
{
"local": {
"appConfig": {
"port": 3003
},
"dbConfig": {
"host": "127.0.0.1",
"port": 5432,
"user": "postgres",
"password": "postgres",
"database": "epr",
"MODE": "PROD",
"loggerEnabled": true
},
"fileConfig": {
"storagePath": "/opt/www/wastecare-uploads/prod",
"configPath": "/opt/wastecare/config/prod"
},
"mailConfig": {
"transport": {
"host": "smtppro.zoho.in",
"secure": true,
"port": 465,
"auth": {
"user": "admin@wct.co.in",
"pass": "Wastecare@123"
}
},
"defaults": {
"from": "\"No Reply\" <admin@wct.co.in>"
}
}
}
}

View File

@ -0,0 +1,34 @@
{
"local": {
"appConfig": {
"port": 3003
},
"dbConfig": {
"host": "127.0.0.1",
"port": 5432,
"user": "postgres",
"password": "postgres",
"database": "epr",
"MODE": "TEST",
"loggerEnabled": true
},
"fileConfig": {
"storagePath": "/opt/www/wastecare-uploads/test",
"configPath": "/opt/wastecare/config/test"
},
"mailConfig": {
"transport": {
"host": "smtppro.zoho.in",
"secure": true,
"port": 465,
"auth": {
"user": "admin@wct.co.in",
"pass": "Wastecare@123"
}
},
"defaults": {
"from": "\"No Reply\" <admin@wct.co.in>"
}
}
}
}

View File

@ -0,0 +1,82 @@
// This file should exist in `src/common/helpers`
import * as fs from 'fs';
import { promisify } from 'util';
/**
* Check if a file exists at a given path.
*
* @param {string} path
*
* @returns {boolean}
*/
export const checkIfFileOrDirectoryExists = (path: string): boolean => {
return fs.existsSync(path);
};
/**
* Gets file data from a given path via a promise interface.
*
* @param {string} path
* @param {string} encoding
*
* @returns {Promise<Buffer>}
*/
export const getFile = async (
path: string,
encoding: string,
): Promise<string | Buffer> => {
const readFile = promisify(fs.readFile);
return encoding ? readFile(path) : readFile(path, {});
};
/**
* Writes a file at a given path via a promise interface.
*
* @param {string} path
* @param {string} fileName
* @param {string} data
*
* @return {Promise<void>}
*/
export const createFile = async (
path: string,
fileName: string,
data: string,
): Promise<void> => {
if (!checkIfFileOrDirectoryExists(path)) {
fs.mkdirSync(path);
}
const writeFile = promisify(fs.writeFile);
return await writeFile(`${path}/${fileName}`, data, 'utf8');
};
export const updateFile = async (
path: string,
fileName: string,
data: string,
): Promise<void> => {
const fqdn = `${path}/${fileName}`
if (!checkIfFileOrDirectoryExists(path)) {
fs.mkdirSync(path);
}
// const writeFile = promisify(fs.writeFile);
return fs.writeFileSync(`${fqdn}`, data);
};
/**
* Delete file at the given path via a promise interface
*
* @param {string} path
*
* @returns {Promise<void>}
*/
export const deleteFile = async (path: string): Promise<void> => {
const unlink = promisify(fs.unlink);
return await unlink(path);
};

View File

@ -0,0 +1,22 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AppController } from './app.controller';
import { AppService } from './app.service';
describe('AppController', () => {
let appController: AppController;
beforeEach(async () => {
const app: TestingModule = await Test.createTestingModule({
controllers: [AppController],
providers: [AppService],
}).compile();
appController = app.get<AppController>(AppController);
});
describe('root', () => {
it('should return "Hello World!"', () => {
expect(appController.getHello()).toBe('Hello World!');
});
});
});

14
src/app.controller.ts Normal file
View File

@ -0,0 +1,14 @@
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {
this.appService.initializeSequelize();
}
@Get()
getHello(): string {
return this.appService.getHello();
}
}

29
src/app.module.ts Normal file
View File

@ -0,0 +1,29 @@
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { CommonService } from './common/common.service';
import { AppConfigService } from './app-config/app-config.service';
import { DataModule } from './data/data.module';
import { MailModule } from './mail/mail.module';
import { AppConfigController } from './app-config/app-config.controller';
import { ConfigModule } from './config/config.module';
import { ActionsModule } from './actions/actions.module';
import { PolicyModule } from './policy/policy.module';
import { ResourcesModule } from './resources/resources.module';
import { RulesModule } from './rules/rules.module';
import { RulesDetailModule } from './rules-detail/rules-detail.module';
@Module({
imports: [
DataModule,
MailModule,
ActionsModule,
PolicyModule,
ResourcesModule,
RulesModule,
RulesDetailModule,
ConfigModule,
],
controllers: [AppController, AppConfigController],
providers: [CommonService, AppConfigService, AppService],
})
export class AppModule { }

76
src/app.service.ts Normal file
View File

@ -0,0 +1,76 @@
import { Injectable } from '@nestjs/common';
import { CommonService } from './common/common.service';
import * as fs from 'fs';
import * as path from 'path';
import { Sequelize } from 'sequelize-typescript';
import { AppConfigService } from './app-config/app-config.service';
import { Utility } from './common/Utility';
@Injectable()
export class AppService {
modelFilePaths: string[] = [] as string[];
constructor(private commonService: CommonService, private configService: AppConfigService) { }
getHello(): string {
return 'Hello World!';
}
initializeSequelize() {
this.getModels();
const dbConfig = this.configService.getDbConfig();
if (this.modelFilePaths.length > 0) {
this.commonService.sequelize = new Sequelize({
database: dbConfig.database,
dialect: 'postgres',
username: dbConfig.user,
password: dbConfig.password,
models: this.modelFilePaths,
modelMatch: (filename, member) => {
return filename.substring(0, filename.indexOf('.entity')) === member.toLowerCase();
},
});
Utility.sequelize = this.commonService.sequelize;
}
const fileConfig = this.configService.initializeFileSystem();
this.commonService.fileConfig = fileConfig;
Utility.fileConfig = fileConfig;
const emailConfig = this.configService.getMailConfig();
this.commonService.mailConfig = emailConfig;
Utility.mailConfig = emailConfig;
}
getModels() {
this.fromDir(__dirname, '.entity', ['.js', '.ts']);
if (this.modelFilePaths.length > 0) {
}
}
fromDir(startPath, filter, extensions) {
if (!fs.existsSync(startPath) || !extensions || extensions.length === 0) {
console.log("no dir ", startPath);
return;
}
const files = fs.readdirSync(startPath);
for (let i = 0; i < files.length; i++) {
const filename = path.join(startPath, files[i]);
const stat = fs.lstatSync(filename);
if (stat.isDirectory()) {
this.fromDir(filename, filter, extensions); //recurse
} else if (filename.includes(filter)) {
extensions.map((extension) => {
if (filename.endsWith(`${filter}${extension}`)) {
this.modelFilePaths.push(filename);
}
})
};
};
}
}

View File

@ -0,0 +1,18 @@
export class Exception {
public exception: boolean;
public exceptionSeverity: 'HIGH' | 'MEDIUM' | 'LOW';
public exceptionMessage: string;
public stackTrace: any;
constructor(
exception,
exceptionSeverity,
exceptionMessage,
stackTrace = null,
) {
this.exception = exception;
this.exceptionSeverity = exceptionSeverity;
this.exceptionMessage = exceptionMessage;
this.stackTrace = stackTrace;
}
}

View File

@ -0,0 +1,14 @@
import { Exception } from "./Exception.model";
export class GenericResponse {
public notification: Exception;
data: any
constructor(
exception: Exception,
data
) {
this.notification = exception;
this.data = data;
}
}

22
src/common/Utility.ts Normal file
View File

@ -0,0 +1,22 @@
import { Sequelize } from "sequelize";
export class Utility {
static sequelize: Sequelize;
static appPort: number = 3000;
static models: any;
static fileConfig: any = {"storagePath": "./uploads"};
static mailConfig: any = {
"transport": {
"host": "smtppro.zoho.in",
"secure": true,
"port": 465,
"auth": {
"user": "admin@wct.co.in",
"pass": "Wastecare@123"
}
},
"defaults": {
"from": "\"No Reply\" <admin@wct.co.in>"
}
};
}

View File

@ -0,0 +1,13 @@
import { Injectable } from '@nestjs/common';
import {Sequelize} from 'sequelize-typescript';
@Injectable()
export class CommonService {
sequelize: Sequelize;
models: any;
fileConfig: any;
mailConfig: any;
constructor() {
}
}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { ConfigLogsController } from './config-logs.controller';
describe('ConfigLogsController', () => {
let controller: ConfigLogsController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [ConfigLogsController],
}).compile();
controller = module.get<ConfigLogsController>(ConfigLogsController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});

View File

@ -0,0 +1,103 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { Response } from 'express';
import { ConfigLogsService } from './config-logs.service';
import ConfigLog from './config-logs.entity';
import { GenericResponse } from 'src/common/GenericResponse.model';
@Controller('config/logs')
export class ConfigLogsController {
constructor(private configService: ConfigLogsService) {}
@Get("/all")
async getAll(@Res() res: Response) {
const response = await this.configService.findAll() || [];
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Get(':id')
async findById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.configService.findByPk(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post('/filter')
async filter(@Body() config: ConfigLog, @Res() res: Response) {
if(!config) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.configService.filter(config) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post()
async insert(@Body() config: ConfigLog, @Res() res: Response) {
if(!config) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
delete config.id;
const response = await this.configService.upsert(config, true);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Put()
async update(@Body() config: ConfigLog, @Res() res: Response) {
if(!config || !config.id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.configService.upsert(config, false);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Delete(':id')
async deleteById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.configService.remove(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
}

View File

@ -0,0 +1,29 @@
import { Table, Column, Model, Default, DataType } from 'sequelize-typescript';
@Table({tableName: 'config_logs', paranoid : true})
export default class ConfigLog extends Model {
@Column({type: DataType.TEXT})
tableName: string;
@Column({type: DataType.TEXT})
prevValue: string;
@Column({type: DataType.TEXT})
currValue: string;
@Default(new Date())
@Column({type: DataType.DATEONLY})
validFrom: Date;
@Default(new Date("2070-12-31"))
@Column({type: DataType.DATEONLY})
validTill: Date;
@Column({type: DataType.TEXT})
createBy: string;
@Column({type: DataType.TEXT})
modifiedBy: string;
}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { ConfigLogsService } from './config-logs.service';
describe('ConfigLogsService', () => {
let service: ConfigLogsService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [ConfigLogsService],
}).compile();
service = module.get<ConfigLogsService>(ConfigLogsService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

View File

@ -0,0 +1,37 @@
import { Injectable } from '@nestjs/common';
import ConfigLog from './config-logs.entity';
@Injectable()
export class ConfigLogsService {
async findAll(): Promise<{rows: ConfigLog[], count: number}> {
return ConfigLog.findAndCountAll();
}
findByPk(id: number): Promise<ConfigLog> {
return ConfigLog.findByPk(id)
}
filter(config: ConfigLog) : Promise<ConfigLog[]> {
return ConfigLog.findAll({where: config as any})
}
findOne(config: ConfigLog): Promise<ConfigLog> {
return ConfigLog.findOne({where: config as any})
}
async remove(id: number): Promise<number> {
return ConfigLog.destroy({where: {id: id}});
}
async upsert(config: ConfigLog, insertIfNotFound: boolean): Promise<ConfigLog | [affectedCount: number]> {
if(config.id) {
const existingUser = await this.findByPk(config.id);
if(existingUser) {
return ConfigLog.update(config, {where: {id: config.id}});
}
}
if(insertIfNotFound) {
return ConfigLog.create(config as any)
}
}
}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { ConfigController } from './config.controller';
describe('ConfigController', () => {
let controller: ConfigController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [ConfigController],
}).compile();
controller = module.get<ConfigController>(ConfigController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});

View File

@ -0,0 +1,104 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { Response } from 'express';
import { ConfigService } from './config.service';
import Config from './config.entity';
import { GenericResponse } from 'src/common/GenericResponse.model';
@Controller('config')
export class ConfigController {
constructor(private configService: ConfigService) {}
@Get("/all")
async getAll(@Res() res: Response) {
const response = await this.configService.findAll() || [];
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Get(':id')
async findById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.configService.findByPk(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post('/filter')
async filter(@Body() config: Config, @Res() res: Response) {
if(!config) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.configService.filter(config) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post()
async insert(@Body() config: Config, @Res() res: Response) {
if(!config) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
delete config.id;
const response = await this.configService.upsert(config, true);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Put()
async update(@Body() config: Config, @Res() res: Response) {
if(!config || !config.id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.configService.upsert(config, false);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Delete(':id')
async deleteById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.configService.remove(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
}

View File

@ -0,0 +1,44 @@
import { Table, Column, Model, Default, DataType } from 'sequelize-typescript';
@Table({tableName: 'config_transcations', paranoid : true})
export default class Config extends Model {
@Column({type: DataType.TEXT})
configCode: string;
@Column({type: DataType.TEXT})
companyCode: string;
@Column({type: DataType.TEXT})
itemCategoryCode: string;
@Column({type: DataType.TEXT})
itemCode: string;
@Column({type: DataType.TEXT})
status: string;
@Column({type: DataType.TEXT})
value: string;
@Column({type: DataType.TEXT})
fileUrl: string;
@Column({type: DataType.NUMBER})
weight: string;
@Default(new Date())
@Column({type: DataType.DATEONLY})
validFrom: Date;
@Default(new Date("2070-12-31"))
@Column({type: DataType.DATEONLY})
validTill: Date;
@Column({type: DataType.TEXT})
createBy: string;
@Column({type: DataType.TEXT})
modifiedBy: string;
}

View File

@ -0,0 +1,11 @@
import { Module } from '@nestjs/common';
import { ConfigController } from './config.controller';
import { ConfigService } from './config.service';
import { ConfigLogsController } from './config-logs/config-logs.controller';
import { ConfigLogsService } from './config-logs/config-logs.service';
@Module({
controllers: [ConfigController, ConfigLogsController],
providers: [ConfigService, ConfigLogsService]
})
export class ConfigModule {}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { ConfigService } from './config.service';
describe('ConfigService', () => {
let service: ConfigService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [ConfigService],
}).compile();
service = module.get<ConfigService>(ConfigService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

View File

@ -0,0 +1,37 @@
import { Injectable } from '@nestjs/common';
import Config from './config.entity';
@Injectable()
export class ConfigService {
async findAll(): Promise<{rows: Config[], count: number}> {
return Config.findAndCountAll();
}
findByPk(id: number): Promise<Config> {
return Config.findByPk(id)
}
filter(config: Config) : Promise<Config[]> {
return Config.findAll({where: config as any})
}
findOne(config: Config): Promise<Config> {
return Config.findOne({where: config as any})
}
async remove(id: number): Promise<number> {
return Config.destroy({where: {id: id}});
}
async upsert(config: Config, insertIfNotFound: boolean): Promise<Config | [affectedCount: number]> {
if(config.id) {
const existingUser = await this.findByPk(config.id);
if(existingUser) {
return Config.update(config, {where: {id: config.id}});
}
}
if(insertIfNotFound) {
return Config.create(config as any)
}
}
}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { DataController } from './data.controller';
describe('DataController', () => {
let controller: DataController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [DataController],
}).compile();
controller = module.get<DataController>(DataController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});

132
src/data/data.controller.ts Normal file
View File

@ -0,0 +1,132 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { GenericResponse } from 'src/common/GenericResponse.model';
import DataModel from './data.entity';
import { DataService } from './data.service';
import { Response } from 'express';
@Controller('data')
export class DataController {
constructor(private dataService: DataService) {}
@Get("/all")
async getAllUsers(@Res() res: Response) {
const response: any = await this.dataService.findAll() || [];
res.send((response && response.rows) ? response.rows : []);
}
@Get(':id')
async findById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.dataService.findByPk(id) || {};
res.send(response);
}
@Post('/:endPtNm/:opType')
async performOperation(@Param('endPtNm') endPtNm: string, @Param('opType') opType: string, @Body() body, @Res() res: Response) {
if(!opType || !endPtNm) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response: DataModel = await this.dataService.findOne({endPtNm: endPtNm, opsTypeName: opType.toUpperCase()} as any);
if(response && response.sqlQueryText) {
if(body) {
for(const key in body) {
response.sqlQueryText = response.sqlQueryText.replaceAll(`:${key}`, (typeof body[key] === 'string') ? `'${body[key]}'` : body[key]);
}
}
let dataResponse = await this.dataService.executeQuery(response.sqlQueryText);
if(dataResponse && dataResponse.length && Array.isArray(dataResponse[0])) {
dataResponse = dataResponse[0];
}
res.send(dataResponse);
return;
}
return new GenericResponse(null, []);
}
@Post('/filter')
async filter(@Body() quote: DataModel, @Res() res: Response) {
if(!quote) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.dataService.filter(quote) || [];
res.send(response);
}
@Post()
async insert(@Body() quote: DataModel, @Res() res: Response) {
if(!quote) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
delete quote.id;
const response = await this.dataService.upsert(quote, true);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Put()
async update(@Body() quote: DataModel, @Res() res: Response) {
if(!quote || !quote.id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.dataService.upsert(quote, false);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Delete(':id')
async deleteById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.dataService.remove(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
}

29
src/data/data.entity.ts Normal file
View File

@ -0,0 +1,29 @@
import { Table, Column, Model, Default, DataType } from 'sequelize-typescript';
@Table({tableName: 'crud_config_info', paranoid : true})
export default class DataModel extends Model {
@Column({type: DataType.NUMBER})
endPtNm: string;
@Column({type: DataType.TEXT})
sqlQueryText: string;
@Column({type: DataType.TEXT})
opsTypeName: string;
@Default(new Date())
@Column({type: DataType.DATEONLY})
validFrom: Date;
@Default(new Date("2070-12-31"))
@Column({type: DataType.DATEONLY})
validTill: Date;
@Column({type: DataType.TEXT})
createBy: string;
@Column({type: DataType.TEXT})
modifiedBy: string;
}

9
src/data/data.module.ts Normal file
View File

@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { DataService } from './data.service';
import { DataController } from './data.controller';
@Module({
providers: [DataService],
controllers: [DataController]
})
export class DataModule {}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { DataService } from './data.service';
describe('DataService', () => {
let service: DataService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [DataService],
}).compile();
service = module.get<DataService>(DataService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

44
src/data/data.service.ts Normal file
View File

@ -0,0 +1,44 @@
import { Injectable } from '@nestjs/common';
import DataModel from './data.entity';
import { Utility } from 'src/common/Utility';
@Injectable()
export class DataService {
constructor() { }
async findAll(): Promise<{rows: DataModel[], count: number}> {
return DataModel.findAndCountAll();
}
findByPk(id: number): Promise<DataModel> {
return DataModel.findByPk(id)
}
findOne(dataDetail: DataModel): Promise<DataModel> {
return DataModel.findOne({where: dataDetail as any})
}
filter(dataDetail: DataModel) : Promise<DataModel[]> {
return DataModel.findAll({where: dataDetail as any})
}
async remove(id: number): Promise<number> {
return DataModel.destroy({where: {id: id}});
}
async upsert(dataDetail: DataModel, insertIfNotFound: boolean): Promise<DataModel | [affectedCount: number]> {
if(dataDetail.id) {
const existingUser = await this.findByPk(dataDetail.id);
if(existingUser) {
return DataModel.update(dataDetail, {where: {id: dataDetail.id}});
}
}
if(insertIfNotFound) {
return DataModel.create(dataDetail as any)
}
}
executeQuery(sqlQueryText: string): Promise<any> {
return Utility.sequelize.query(sqlQueryText);
}
}

27
src/mail/mail.module.ts Normal file
View File

@ -0,0 +1,27 @@
import { MailerModule } from '@nestjs-modules/mailer';
import { HandlebarsAdapter } from '@nestjs-modules/mailer/dist/adapters/handlebars.adapter';
import { Module } from '@nestjs/common';
import { MailService } from './mail.service';
import { join } from 'path';
import { Utility } from 'src/common/Utility';
@Module({
imports: [
MailerModule.forRoot({
// transport: 'smtps://user@example.com:topsecret@smtp.example.com',
// or
transport: Utility.mailConfig.transport,
defaults: Utility.mailConfig.defaults,
template: {
dir: join(__dirname, 'templates'),
adapter: new HandlebarsAdapter(), // or new PugAdapter() or new EjsAdapter()
options: {
strict: true,
},
},
}),
],
providers: [MailService],
exports: [MailService], // 👈 export for DI
})
export class MailModule {}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { MailService } from './mail.service';
describe('MailService', () => {
let service: MailService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [MailService],
}).compile();
service = module.get<MailService>(MailService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

19
src/mail/mail.service.ts Normal file
View File

@ -0,0 +1,19 @@
import { MailerService } from '@nestjs-modules/mailer';
import { Injectable } from '@nestjs/common';
@Injectable()
export class MailService {
constructor(private mailerService: MailerService) { }
async sendEmail(templateName: string, subject: string, context: any, toEmail: string, ccEmails?: string[], bccEmails?: string[]) {
await this.mailerService.sendMail({
to: toEmail,
cc: ccEmails,
bcc: bccEmails,
subject: subject,
template: templateName, // `.hbs` extension is appended automatically
context,
})
}
}

View File

@ -0,0 +1,82 @@
<head>
<style>
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.gjs-row {
display: flex;
justify-content: flex-start;
align-items: stretch;
flex-wrap: nowrap;
padding: 10px;
}
.gjs-cell {
min-height: 75px;
flex-grow: 1;
flex-basis: 100%;
}
#im43 {
background-repeat: repeat;
background-position: left top;
background-attachment: scroll;
background-size: auto;
background-image: linear-gradient(#39960c 0%, #39960c 100%);
}
#ij93 {
padding: 10px;
}
#ilfj {
color: #ffffff;
text-align: left;
font-weight: 900;
font-size: 3rem;
}
#ihfp {
height: 577px;
}
#i23r {
padding: 10px;
}
@media (max-width: 768px) {
.gjs-row {
flex-wrap: wrap;
}
}
</style>
</head>
<body id="iohk">
<div class="gjs-row" id="iir1">
<div class="gjs-cell" id="im43">
<div id="ij93">
<span id="ilfj">Waste Care Technologies</span>
</div>
</div>
</div>
<div class="gjs-row" id="ihfp">
<div class="gjs-cell">
<div id="i23r">Dear {{ name }},
<br />
<br />Welcome to Waste Care Technologies.
<br />
<br />Use Password {{ password }} to login to your account.
<br />
<br />Contact our Support if you need any queries.
<br />
<br />Thank you for choosing us
</div>
</div>
</div>
</body>

View File

@ -0,0 +1,79 @@
<head>
<style>
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.gjs-row {
display: flex;
justify-content: flex-start;
align-items: stretch;
flex-wrap: nowrap;
padding: 10px;
}
.gjs-cell {
min-height: 75px;
flex-grow: 1;
flex-basis: 100%;
}
#im43 {
background-repeat: repeat;
background-position: left top;
background-attachment: scroll;
background-size: auto;
background-image: linear-gradient(#39960c 0%, #39960c 100%);
}
#ij93 {
padding: 10px;
}
#ilfj {
color: #ffffff;
text-align: left;
font-weight: 900;
font-size: 3rem;
}
#ihfp {
height: 577px;
}
#i23r {
padding: 10px;
}
@media (max-width: 768px) {
.gjs-row {
flex-wrap: wrap;
}
}
</style>
</head>
<body id="iohk">
<div class="gjs-row" id="iir1">
<div class="gjs-cell" id="im43">
<div id="ij93">
<span id="ilfj">Waste Care Technologies</span>
</div>
</div>
</div>
<div class="gjs-row" id="ihfp">
<div class="gjs-cell" id="ihbs">
<div id="i23r">Dear {{ email }},
<br/>
<br/>A Quote with {{ quoteID }} is created by you.
<br/>
<br/>Current Quote is in {{ status }} status.
<br/>
<br/>Thank you for choosing us
</div>
</div>
</div>
</body>

16
src/main.ts Normal file
View File

@ -0,0 +1,16 @@
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as bodyParser from 'body-parser';
import * as configMaster from './app-config/config.json';
import { Utility } from './common/Utility';
async function bootstrap() {
Utility.appPort = configMaster.local.appConfig.port;
Utility.mailConfig = configMaster.local.mailConfig;
Utility.fileConfig = configMaster.local.fileConfig;
const app = await NestFactory.create(AppModule, { cors: true });
app.use(bodyParser.json({limit: '50mb'}));
app.use(bodyParser.urlencoded({limit: '50mb', extended: true}));
await app.listen(Utility.appPort);
}
bootstrap();

View File

@ -0,0 +1,106 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { PolicyService } from './policy.service';
import { Response } from 'express';
import { GenericResponse } from '../common/GenericResponse.model';
import Policy from './policy.entity';
@Controller('policy')
export class PolicyController {
constructor(private policyService: PolicyService) {}
@Get("/all")
async getAllPolicys(@Res() res: Response) {
const response = await this.policyService.findAll() || [];
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Get(':id')
async findById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.policyService.findByPk(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post('/filter')
async filter(@Body() policy: Policy, @Res() res: Response) {
if(!policy) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.policyService.filter(policy) || [];
const httpResponse = new GenericResponse(null, response)
res.status(200).send(httpResponse);
}
@Post()
async insert(@Body() policy: Policy, @Res() res: Response) {
if(!policy) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
delete policy.id;
const response = await this.policyService.upsert(policy, true);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Put()
async update(@Body() policy: Policy, @Res() res: Response) {
if(!policy || !policy.id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.policyService.upsert(policy, false);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Delete(':id')
async deleteById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.policyService.remove(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
}

View File

@ -0,0 +1,49 @@
import { Table, Column, Model, Default, DataType } from 'sequelize-typescript';
@Table({ tableName: 'policies_ref' , paranoid : true})
export default class Policy extends Model {
@Column(DataType.TEXT)
appCode: string;
@Column(DataType.TEXT)
roleCode: string;
@Column(DataType.TEXT)
resourceCode: string;
@Column(DataType.TEXT)
actionCode: string;
@Column(DataType.BOOLEAN)
canAllow: boolean;
@Column(DataType.NUMBER)
priority: number;
@Default(new Date())
@Column(DataType.DATEONLY)
validFrom: Date;
@Default(new Date("2070-12-31"))
@Column(DataType.DATEONLY)
validTo: Date;
@Column(DataType.DATEONLY)
createdAt: Date;
@Column(DataType.DATEONLY)
updatedAt: Date;
@Column(DataType.TEXT)
createdBy: string;
@Column(DataType.TEXT)
modifiedBy: string;
@Column(DataType.DATEONLY)
deletedAt: Date;
@Column(DataType.NUMBER)
version: number;
}

View File

@ -0,0 +1,10 @@
import { Module } from '@nestjs/common';
import { PolicyController } from './policy.controller';
import { PolicyService } from './policy.service';
@Module({
providers: [PolicyService],
controllers: [PolicyController],
imports: []
})
export class PolicyModule { }

View File

@ -0,0 +1,41 @@
import { Injectable } from '@nestjs/common';
import Policy from './policy.entity';
@Injectable()
export class PolicyService {
constructor() { }
async findAll(): Promise<{ rows: Policy[], count: number }> {
return Policy.findAndCountAll();
}
findByPk(id: number): Promise<Policy> {
return Policy.findByPk(id,)
}
findOne(policy: Policy): Promise<Policy> {
return Policy.findOne({ where: policy as any, })
}
filter(policy: Policy): Promise<Policy[]> {
return Policy.findAll({ where: policy as any, })
}
async remove(id: number): Promise<number> {
return Policy.destroy({ where: { id: id } });
}
async upsert(policy: Policy, insertIfNotFound: boolean): Promise<Policy | [affectedCount: number]> {
if (policy.id) {
const existingPolicy = await this.findByPk(policy.id);
if (existingPolicy) {
return Policy.update(policy, { where: { id: policy.id } });
}
}
if (insertIfNotFound) {
return Policy.create(policy as any)
}
}
}

View File

@ -0,0 +1,106 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { ResourcesService } from './resources.service';
import { Response } from 'express';
import { GenericResponse } from '../common/GenericResponse.model';
import Resources from './resources.entity';
@Controller('resources')
export class ResourcesController {
constructor(private resourcesService: ResourcesService) {}
@Get("/all")
async getAllResourcess(@Res() res: Response) {
const response = await this.resourcesService.findAll() || [];
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Get(':id')
async findById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.resourcesService.findByPk(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post('/filter')
async filter(@Body() resources: Resources, @Res() res: Response) {
if(!resources) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.resourcesService.filter(resources) || [];
const httpResponse = new GenericResponse(null, response)
res.status(200).send(httpResponse);
}
@Post()
async insert(@Body() resources: Resources, @Res() res: Response) {
if(!resources) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
delete resources.id;
const response = await this.resourcesService.upsert(resources, true);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Put()
async update(@Body() resources: Resources, @Res() res: Response) {
if(!resources || !resources.id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.resourcesService.upsert(resources, false);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Delete(':id')
async deleteById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.resourcesService.remove(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
}

View File

@ -0,0 +1,40 @@
import { Table, Column, Model, Default, DataType } from 'sequelize-typescript';
@Table({ tableName: 'resources_ref' , paranoid : true})
export default class Resources extends Model {
@Column(DataType.TEXT)
appCode: string;
@Column(DataType.TEXT)
resourceCode: string;
@Column(DataType.TEXT)
resourceName: string;
@Default(new Date())
@Column(DataType.DATEONLY)
validFrom: Date;
@Default(new Date("2070-12-31"))
@Column(DataType.DATEONLY)
validTo: Date;
@Column(DataType.DATEONLY)
createdAt: Date;
@Column(DataType.DATEONLY)
updatedAt: Date;
@Column(DataType.TEXT)
createdBy: string;
@Column(DataType.TEXT)
modifiedBy: string;
@Column(DataType.DATEONLY)
deletedAt: Date;
@Column(DataType.NUMBER)
version: number;
}

View File

@ -0,0 +1,10 @@
import { Module } from '@nestjs/common';
import { ResourcesController } from './resources.controller';
import { ResourcesService } from './resources.service';
@Module({
providers: [ResourcesService],
controllers: [ResourcesController],
imports: []
})
export class ResourcesModule { }

View File

@ -0,0 +1,41 @@
import { Injectable } from '@nestjs/common';
import Resources from './resources.entity';
@Injectable()
export class ResourcesService {
constructor() { }
async findAll(): Promise<{ rows: Resources[], count: number }> {
return Resources.findAndCountAll();
}
findByPk(id: number): Promise<Resources> {
return Resources.findByPk(id,)
}
findOne(resources: Resources): Promise<Resources> {
return Resources.findOne({ where: resources as any, })
}
filter(resources: Resources): Promise<Resources[]> {
return Resources.findAll({ where: resources as any, })
}
async remove(id: number): Promise<number> {
return Resources.destroy({ where: { id: id } });
}
async upsert(resources: Resources, insertIfNotFound: boolean): Promise<Resources | [affectedCount: number]> {
if (resources.id) {
const existingResources = await this.findByPk(resources.id);
if (existingResources) {
return Resources.update(resources, { where: { id: resources.id } });
}
}
if (insertIfNotFound) {
return Resources.create(resources as any)
}
}
}

View File

@ -0,0 +1,106 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { RulesDetailService } from './rules-detail.service';
import { Response } from 'express';
import { GenericResponse } from '../common/GenericResponse.model';
import RulesDetail from './rules-detail.entity';
@Controller('rulesDetail')
export class RulesDetailController {
constructor(private rulesDetailService: RulesDetailService) {}
@Get("/all")
async getAllRulesDetails(@Res() res: Response) {
const response = await this.rulesDetailService.findAll() || [];
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Get(':id')
async findById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.rulesDetailService.findByPk(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post('/filter')
async filter(@Body() rulesDetail: RulesDetail, @Res() res: Response) {
if(!rulesDetail) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.rulesDetailService.filter(rulesDetail) || [];
const httpResponse = new GenericResponse(null, response)
res.status(200).send(httpResponse);
}
@Post()
async insert(@Body() rulesDetail: RulesDetail, @Res() res: Response) {
if(!rulesDetail) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
delete rulesDetail.id;
const response = await this.rulesDetailService.upsert(rulesDetail, true);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Put()
async update(@Body() rulesDetail: RulesDetail, @Res() res: Response) {
if(!rulesDetail || !rulesDetail.id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.rulesDetailService.upsert(rulesDetail, false);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Delete(':id')
async deleteById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.rulesDetailService.remove(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
}

View File

@ -0,0 +1,40 @@
import { Table, Column, Model, Default, DataType } from 'sequelize-typescript';
@Table({ tableName: 'rules_details_ref' , paranoid : true})
export default class RulesDetail extends Model {
@Column(DataType.TEXT)
ruleCode: string;
@Column(DataType.TEXT)
ruleAttrName: string;
@Column(DataType.TEXT)
ruleAttrText: string;
@Default(new Date())
@Column(DataType.DATEONLY)
validFrom: Date;
@Default(new Date("2070-12-31"))
@Column(DataType.DATEONLY)
validTo: Date;
@Column(DataType.DATEONLY)
createdAt: Date;
@Column(DataType.DATEONLY)
updatedAt: Date;
@Column(DataType.TEXT)
createdBy: string;
@Column(DataType.TEXT)
modifiedBy: string;
@Column(DataType.DATEONLY)
deletedAt: Date;
@Column(DataType.NUMBER)
version: number;
}

View File

@ -0,0 +1,10 @@
import { Module } from '@nestjs/common';
import { RulesDetailController } from './rules-detail.controller';
import { RulesDetailService } from './rules-detail.service';
@Module({
providers: [RulesDetailService],
controllers: [RulesDetailController],
imports: []
})
export class RulesDetailModule { }

View File

@ -0,0 +1,41 @@
import { Injectable } from '@nestjs/common';
import RulesDetail from './rules-detail.entity';
@Injectable()
export class RulesDetailService {
constructor() { }
async findAll(): Promise<{ rows: RulesDetail[], count: number }> {
return RulesDetail.findAndCountAll();
}
findByPk(id: number): Promise<RulesDetail> {
return RulesDetail.findByPk(id,)
}
findOne(rulesDetail: RulesDetail): Promise<RulesDetail> {
return RulesDetail.findOne({ where: rulesDetail as any, })
}
filter(rulesDetail: RulesDetail): Promise<RulesDetail[]> {
return RulesDetail.findAll({ where: rulesDetail as any, })
}
async remove(id: number): Promise<number> {
return RulesDetail.destroy({ where: { id: id } });
}
async upsert(rulesDetail: RulesDetail, insertIfNotFound: boolean): Promise<RulesDetail | [affectedCount: number]> {
if (rulesDetail.id) {
const existingRulesDetail = await this.findByPk(rulesDetail.id);
if (existingRulesDetail) {
return RulesDetail.update(rulesDetail, { where: { id: rulesDetail.id } });
}
}
if (insertIfNotFound) {
return RulesDetail.create(rulesDetail as any)
}
}
}

View File

@ -0,0 +1,106 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { RulesService } from './rules.service';
import { Response } from 'express';
import { GenericResponse } from '../common/GenericResponse.model';
import Rules from './rules.entity';
@Controller('rules')
export class RulesController {
constructor(private rulesService: RulesService) {}
@Get("/all")
async getAllRuless(@Res() res: Response) {
const response = await this.rulesService.findAll() || [];
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Get(':id')
async findById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.rulesService.findByPk(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Post('/filter')
async filter(@Body() rules: Rules, @Res() res: Response) {
if(!rules) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.rulesService.filter(rules) || [];
const httpResponse = new GenericResponse(null, response)
res.status(200).send(httpResponse);
}
@Post()
async insert(@Body() rules: Rules, @Res() res: Response) {
if(!rules) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
delete rules.id;
const response = await this.rulesService.upsert(rules, true);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Put()
async update(@Body() rules: Rules, @Res() res: Response) {
if(!rules || !rules.id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.rulesService.upsert(rules, false);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
@Delete(':id')
async deleteById(@Param('id') id: number, @Res() res: Response) {
if(!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
res.send(response);
return;
}
const response = await this.rulesService.remove(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
}
}

46
src/rules/rules.entity.ts Normal file
View File

@ -0,0 +1,46 @@
import { Table, Column, Model, Default, DataType } from 'sequelize-typescript';
@Table({ tableName: 'rules_ref' , paranoid : true})
export default class Rules extends Model {
@Column(DataType.TEXT)
ruleCode: string;
@Column(DataType.TEXT)
ruleName: string;
@Column(DataType.TEXT)
ruleType: string;
@Column(DataType.TEXT)
ruleDesc: string;
@Column(DataType.TEXT)
ruleText: string;
@Default(new Date())
@Column(DataType.DATEONLY)
validFrom: Date;
@Default(new Date("2070-12-31"))
@Column(DataType.DATEONLY)
validTo: Date;
@Column(DataType.DATEONLY)
createdAt: Date;
@Column(DataType.DATEONLY)
updatedAt: Date;
@Column(DataType.TEXT)
createdBy: string;
@Column(DataType.TEXT)
modifiedBy: string;
@Column(DataType.DATEONLY)
deletedAt: Date;
@Column(DataType.NUMBER)
version: number;
}

10
src/rules/rules.module.ts Normal file
View File

@ -0,0 +1,10 @@
import { Module } from '@nestjs/common';
import { RulesController } from './rules.controller';
import { RulesService } from './rules.service';
@Module({
providers: [RulesService],
controllers: [RulesController],
imports: []
})
export class RulesModule { }

View File

@ -0,0 +1,41 @@
import { Injectable } from '@nestjs/common';
import Rules from './rules.entity';
@Injectable()
export class RulesService {
constructor() { }
async findAll(): Promise<{ rows: Rules[], count: number }> {
return Rules.findAndCountAll();
}
findByPk(id: number): Promise<Rules> {
return Rules.findByPk(id,)
}
findOne(rules: Rules): Promise<Rules> {
return Rules.findOne({ where: rules as any, })
}
filter(rules: Rules): Promise<Rules[]> {
return Rules.findAll({ where: rules as any, })
}
async remove(id: number): Promise<number> {
return Rules.destroy({ where: { id: id } });
}
async upsert(rules: Rules, insertIfNotFound: boolean): Promise<Rules | [affectedCount: number]> {
if (rules.id) {
const existingRules = await this.findByPk(rules.id);
if (existingRules) {
return Rules.update(rules, { where: { id: rules.id } });
}
}
if (insertIfNotFound) {
return Rules.create(rules as any)
}
}
}

24
test/app.e2e-spec.ts Normal file
View File

@ -0,0 +1,24 @@
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import { AppModule } from './../src/app.module';
describe('AppController (e2e)', () => {
let app: INestApplication;
beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
it('/ (GET)', () => {
return request(app.getHttpServer())
.get('/')
.expect(200)
.expect('Hello World!');
});
});

9
test/jest-e2e.json Normal file
View File

@ -0,0 +1,9 @@
{
"moduleFileExtensions": ["js", "json", "ts"],
"rootDir": ".",
"testEnvironment": "node",
"testRegex": ".e2e-spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
}
}

4
tsconfig.build.json Normal file
View File

@ -0,0 +1,4 @@
{
"extends": "./tsconfig.json",
"exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
}

22
tsconfig.json Normal file
View File

@ -0,0 +1,22 @@
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"target": "ES2021",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true,
"skipLibCheck": true,
"strictNullChecks": false,
"noImplicitAny": false,
"strictBindCallApply": false,
"forceConsistentCasingInFileNames": false,
"noFallthroughCasesInSwitch": false,
"resolveJsonModule": true,
}
}