forked from Samagra-Development/workflow
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #106 from Samagra-Anamaya/ste
feat: add scheme transaction APIs
- Loading branch information
Showing
13 changed files
with
662 additions
and
0 deletions.
There are no files selected for viewing
37 changes: 37 additions & 0 deletions
37
packages/bff/prisma/migrations/20231204115049_ste/migration.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
-- CreateTable | ||
CREATE TABLE "scheme_transaction" ( | ||
"id" SERIAL NOT NULL, | ||
"scheme_code" TEXT NOT NULL, | ||
"aadhaar_number" VARCHAR(12) NOT NULL, | ||
"aadhaar_reference_number" VARCHAR(13) NOT NULL, | ||
"unique_beneficiary_id" VARCHAR(127) NOT NULL, | ||
"financial_year" VARCHAR(15) NOT NULL, | ||
"transaction_type" VARCHAR(127) NOT NULL, | ||
"transaction_amount" INTEGER NOT NULL, | ||
"in_kind_benefit_detail" VARCHAR(127) NOT NULL, | ||
"transaction_date" VARCHAR(15) NOT NULL, | ||
"remarks" TEXT, | ||
"department_data" JSONB, | ||
"user_id" UUID NOT NULL, | ||
|
||
CONSTRAINT "scheme_transaction_pkey" PRIMARY KEY ("id") | ||
); | ||
|
||
-- CreateTable | ||
CREATE TABLE "transaction_history_table" ( | ||
"id" UUID NOT NULL DEFAULT gen_random_uuid(), | ||
"request_body" JSONB[], | ||
"total_records" INTEGER NOT NULL, | ||
"valid_records" INTEGER NOT NULL, | ||
"invalid_records" INTEGER NOT NULL, | ||
"contain_errors" BOOLEAN NOT NULL DEFAULT false, | ||
"valid_records_saved" BOOLEAN NOT NULL DEFAULT false, | ||
"errors" JSONB NOT NULL, | ||
"user_id" UUID NOT NULL, | ||
"transaction_start_time" TIMESTAMP(3) NOT NULL, | ||
"transaction_end_time" TIMESTAMP(3) NOT NULL, | ||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
"updated_at" TIMESTAMP(3) NOT NULL, | ||
|
||
CONSTRAINT "transaction_history_table_pkey" PRIMARY KEY ("id") | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import { SetMetadata } from '@nestjs/common'; | ||
|
||
export const Public = () => SetMetadata('isPublic', true); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import { | ||
CanActivate, | ||
ExecutionContext, | ||
Injectable, | ||
Scope, | ||
} from '@nestjs/common'; | ||
import { Observable } from 'rxjs'; | ||
import * as jwt from 'jsonwebtoken'; | ||
import * as jwksClient from 'jwks-rsa'; | ||
import { Reflector } from '@nestjs/core'; | ||
|
||
@Injectable({ scope: Scope.DEFAULT }) | ||
export class SteAuthGuard implements CanActivate { | ||
private client: jwksClient.JwksClient; | ||
private getKey: any; | ||
|
||
constructor(private readonly reflector: Reflector) { | ||
this.client = jwksClient({ | ||
jwksUri: process.env.JWKS_URI, | ||
requestHeaders: {}, // Optional | ||
timeout: 30000, // Defaults to 30s | ||
}); | ||
|
||
this.getKey = (header: jwt.JwtHeader, callback: any) => { | ||
this.client.getSigningKey(header.kid, (err, key: any) => { | ||
if (err) { | ||
console.log(`Error fetching signing key: ${err}`); | ||
callback(err); | ||
} else { | ||
const signingKey = key.publicKey || key.rsaPublicKey; | ||
callback(null, signingKey); | ||
} | ||
}); | ||
}; | ||
} | ||
|
||
canActivate( | ||
context: ExecutionContext, | ||
): boolean | Promise<boolean> | Observable<boolean> { | ||
const isPublic = this.reflector.get<boolean>( | ||
'isPublic', | ||
context.getHandler(), | ||
); | ||
if (isPublic) return true; | ||
const request = context.switchToHttp().getRequest(); | ||
|
||
const bearerToken = request.headers.authorization?.split(' ')[1]; | ||
|
||
if (!bearerToken) { | ||
return false; | ||
} | ||
|
||
return new Promise<boolean>((resolve) => { | ||
jwt.verify(bearerToken, this.getKey, (err, decoded) => { | ||
if (err) { | ||
console.log('JWT verification error:', err); | ||
resolve(false); | ||
} else { | ||
if (!decoded['roles'].includes('department')) { | ||
resolve(false); | ||
} | ||
request.headers.userId = decoded.sub; | ||
request.headers.username = decoded['preferred_username']; | ||
request.headers.roles = decoded['roles']; | ||
resolve(true); | ||
} | ||
}); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { ApiProperty } from '@nestjs/swagger'; | ||
|
||
export class AuthDto { | ||
@ApiProperty() | ||
username: string; | ||
|
||
@ApiProperty() | ||
password: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import { ApiProperty } from '@nestjs/swagger'; | ||
import { JsonArray } from '@prisma/client/runtime/library'; | ||
|
||
export class SchemeTransactionEvent { | ||
@ApiProperty({ | ||
example: 'CULC8', | ||
}) | ||
schemeCode: string; | ||
|
||
@ApiProperty({ | ||
example: '123412341234', | ||
description: '12 Digit Aadhaar Number', | ||
}) | ||
aadhaarNumber: string; | ||
|
||
@ApiProperty({ | ||
example: '1234123412345', | ||
description: '13 Digit Aadhaar Reference Number', | ||
}) | ||
aadhaarReferenceNumber: string; | ||
|
||
@ApiProperty({ | ||
example: '123456', | ||
}) | ||
uniqueBeneficiaryId: string; | ||
|
||
@ApiProperty({ | ||
example: '2022-23', | ||
description: 'Financial year in YYYY-YY format', | ||
}) | ||
financialYear: string; | ||
|
||
@ApiProperty({ | ||
example: 'Cash', | ||
}) | ||
transactionType: string; | ||
|
||
@ApiProperty({ | ||
example: 5000, | ||
description: 'Transaction Amount', | ||
}) | ||
transactionAmount: number; | ||
|
||
@ApiProperty({ | ||
example: 'Training', | ||
}) | ||
inKindBenefitDetail: string; | ||
|
||
@ApiProperty({ | ||
example: '12-05-2023', | ||
description: 'Transaction date in DD-MM-YYYY format', | ||
}) | ||
transactionDate: string; | ||
|
||
@ApiProperty({ | ||
type: String, | ||
}) | ||
remarks = ''; | ||
|
||
@ApiProperty({ | ||
type: [], | ||
example: [ | ||
{ | ||
marker: 'Date of Birth', | ||
value: '21-01-1999', | ||
}, | ||
], | ||
description: 'These are department specific marker-value pairs', | ||
}) | ||
departmentData: JsonArray = []; | ||
} | ||
|
||
export class SchemeTransactionEventDto { | ||
@ApiProperty({ | ||
type: [SchemeTransactionEvent], | ||
}) | ||
data: SchemeTransactionEvent[]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { Test, TestingModule } from '@nestjs/testing'; | ||
import { SteController } from './ste.controller'; | ||
|
||
describe('SteController', () => { | ||
let controller: SteController; | ||
|
||
beforeEach(async () => { | ||
const module: TestingModule = await Test.createTestingModule({ | ||
controllers: [SteController], | ||
}).compile(); | ||
|
||
controller = module.get<SteController>(SteController); | ||
}); | ||
|
||
it('should be defined', () => { | ||
expect(controller).toBeDefined(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { | ||
Body, | ||
Controller, | ||
Get, | ||
Param, | ||
Post, | ||
Req, | ||
UseGuards, | ||
} from '@nestjs/common'; | ||
import { SteService } from './ste.service'; | ||
import { SchemeTransactionEventDto } from './dto/scheme.transaction.dto'; | ||
import { Public } from 'src/common/public.decorator'; | ||
import { Request } from 'express'; | ||
import { SteAuthGuard } from 'src/common/ste.auth-guard'; | ||
import { AuthDto } from './dto/auth.dto'; | ||
|
||
@UseGuards(SteAuthGuard) | ||
@Controller('ste') | ||
export class SteController { | ||
constructor(private readonly steService: SteService) {} | ||
|
||
@Public() | ||
@Post('/authenticate') | ||
async authenticate(@Body() authDto: AuthDto) { | ||
return await this.steService.authenticate( | ||
authDto.username, | ||
authDto.password, | ||
); | ||
} | ||
|
||
@Post('/saveSchemeTransaction') | ||
async saveSchemeTransaction( | ||
@Body() schemeTransactionDetail: SchemeTransactionEventDto, | ||
@Req() request: Request, | ||
) { | ||
const userIdHeader = request.headers.userId; | ||
const userId: string = Array.isArray(userIdHeader) | ||
? userIdHeader[0] | ||
: userIdHeader; | ||
return await this.steService.saveSchemeTransaction( | ||
schemeTransactionDetail.data, | ||
userId, | ||
); | ||
} | ||
|
||
@Get('/transactionHistory/:id') | ||
async getTransactionHistory(@Param('id') transactionHistoryid: string) { | ||
return await this.steService.getTransactionHistory(transactionHistoryid); | ||
} | ||
|
||
@Get('/progress') | ||
async getProgress(@Req() request: Request) { | ||
const userIdHeader = request.headers.userId; | ||
const userId: string = Array.isArray(userIdHeader) | ||
? userIdHeader[0] | ||
: userIdHeader; | ||
return await this.steService.getProgress(userId); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import { Module } from '@nestjs/common'; | ||
|
||
@Module({}) | ||
export class SteModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { Test, TestingModule } from '@nestjs/testing'; | ||
import { SteService } from './ste.service'; | ||
|
||
describe('SteService', () => { | ||
let service: SteService; | ||
|
||
beforeEach(async () => { | ||
const module: TestingModule = await Test.createTestingModule({ | ||
providers: [SteService], | ||
}).compile(); | ||
|
||
service = module.get<SteService>(SteService); | ||
}); | ||
|
||
it('should be defined', () => { | ||
expect(service).toBeDefined(); | ||
}); | ||
}); |
Oops, something went wrong.