Feature/33 api fails when no pilots or logbook entries (#35)
* api no longer fails when no pilots or logbook entries * api no longer fails when no pilots or logbook entries * api no longer fails when no pilots or logbook entries * api no longer fails when no pilots or logbook entries * api no longer fails when no pilots or logbook entries * api no longer fails when no pilots or logbook entries * api no longer fails when no pilots or logbook entries * api no longer fails when no pilots or logbook entries * api no longer fails when no pilots or logbook entries * api no longer fails when no pilots or logbook entries * api no longer fails when no pilots or logbook entries * api no longer fails when no pilots or logbook entries * api no longer fails when no pilots or logbook entries * api no longer fails when no pilots or logbook entries * api no longer fails when no pilots or logbook entries * api no longer fails when no pilots or logbook entries * api no longer fails when no pilots or logbook entries * api no longer fails when no pilots or logbook entries * api no longer fails when no pilots or logbook entries * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * Refactoring * refactoring * refactoring * refactoring * refactoring * adding test environment * adding test environment
This commit was merged in pull request #35.
This commit is contained in:
@@ -3,54 +3,23 @@ import {
|
||||
Get,
|
||||
Headers,
|
||||
Query,
|
||||
Res,
|
||||
StreamableFile
|
||||
StreamableFile,
|
||||
UseGuards
|
||||
} from '@nestjs/common';
|
||||
import {
|
||||
AppConfigService,
|
||||
MsGraphService,
|
||||
MsGraphClient
|
||||
} from '@noahspan/noahspan-modules';
|
||||
import { FeatureFlagValue } from '@azure/app-configuration';
|
||||
import { Public } from '@noahspan/noahspan-modules';
|
||||
import { Client as MsGraphClient } from '@microsoft/microsoft-graph-client';
|
||||
import { MsGraphService } from './msGraph/ms-graph.service'
|
||||
import { Person } from '@microsoft/microsoft-graph-types';
|
||||
import { AppService } from './app.service';
|
||||
import { createReadStream } from 'fs';
|
||||
import { join } from 'path';
|
||||
import { arrayBuffer } from 'stream/consumers';
|
||||
import type { Response } from 'express';
|
||||
import { AuthGuard } from '@nestjs/passport';
|
||||
|
||||
@Controller()
|
||||
@UseGuards(AuthGuard('azure-ad'))
|
||||
export class AppController {
|
||||
constructor(
|
||||
private readonly appService: AppService,
|
||||
private readonly appConfigService: AppConfigService,
|
||||
private readonly msGraphService: MsGraphService
|
||||
) {}
|
||||
|
||||
@Public()
|
||||
@Get('featureFlags')
|
||||
async getFeatureFlags(
|
||||
@Query() query: any
|
||||
): Promise<{ key: string; enabled: boolean }[]> {
|
||||
try {
|
||||
const featureFlagKeys: string[] =
|
||||
query.keys && query.keys.toString().includes(';')
|
||||
? query.keys.split(';')
|
||||
: [query.keys];
|
||||
const featureFlagLabel: string = query.label;
|
||||
const featureFlags: { key: string; enabled: boolean }[] =
|
||||
await this.appConfigService.getFeatureFlags(
|
||||
featureFlagKeys,
|
||||
featureFlagLabel
|
||||
);
|
||||
|
||||
return featureFlags;
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
@Get('userPhoto')
|
||||
async getProfilePhoto(@Headers() headers: any): Promise<StreamableFile> {
|
||||
try {
|
||||
@@ -106,7 +75,6 @@ export class AppController {
|
||||
}
|
||||
}
|
||||
|
||||
@Public()
|
||||
@Get('hello')
|
||||
async getHello(): Promise<string> {
|
||||
return this.appService.getHello();
|
||||
|
||||
@@ -1,47 +1,49 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { AppController } from './app.controller';
|
||||
import { AppService } from './app.service';
|
||||
import {
|
||||
AppConfigModule,
|
||||
AuthModule,
|
||||
AuthGuard,
|
||||
MsGraphModule
|
||||
} from '@noahspan/noahspan-modules';
|
||||
import { ConfigModule } from '@nestjs/config';
|
||||
import { APP_GUARD } from '@nestjs/core';
|
||||
import { LogbookModule } from './logbook/logbook.module';
|
||||
import { AuthModule } from './auth/auth.module';
|
||||
import { MsGraphModule } from './msGraph/ms-graph.module';
|
||||
import { FeatureFlagModule } from './featureFlag/feature-flag.module'
|
||||
import { LogModule } from './log/log.module';
|
||||
import { PilotModule } from './pilot/pilot.module';
|
||||
import { APP_FILTER } from '@nestjs/core';
|
||||
import { HttpExceptionFilter } from './filters/http-exception.filter';
|
||||
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||
import configuration from './config/configuration';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
ConfigModule.forRoot(),
|
||||
AppConfigModule.register({
|
||||
url: process.env.APP_CONFIG_URL,
|
||||
tenantId: process.env.TENANT_ID,
|
||||
clientId: process.env.CLIENT_ID,
|
||||
clientSecret: process.env.CLIENT_SECRET
|
||||
AuthModule.registerAsync({
|
||||
imports: [ConfigModule],
|
||||
useFactory: async (configService: ConfigService) => {
|
||||
return {
|
||||
clientId: configService.get<string>('clientId'),
|
||||
clientSecret: configService.get<string>('clientSecret'),
|
||||
tenantId: configService.get<string>('tenantId')
|
||||
};
|
||||
},
|
||||
inject: [ConfigService]
|
||||
}),
|
||||
AuthModule.register({
|
||||
tenantId: process.env.TENANT_ID,
|
||||
clientId: process.env.CLIENT_ID,
|
||||
clientSecret: process.env.CLIENT_SECRET
|
||||
ConfigModule.forRoot({
|
||||
load: [configuration]
|
||||
}),
|
||||
MsGraphModule.register({
|
||||
tenantId: process.env.TENANT_ID,
|
||||
clientId: process.env.CLIENT_ID,
|
||||
clientSecret: process.env.CLIENT_SECRET
|
||||
FeatureFlagModule,
|
||||
LogModule,
|
||||
MsGraphModule.registerAsync({
|
||||
imports: [ConfigModule],
|
||||
useFactory: async (configService: ConfigService) => {
|
||||
return {
|
||||
clientId: configService.get<string>('clientId'),
|
||||
clientSecret: configService.get<string>('clientSecret'),
|
||||
tenantId: configService.get<string>('tenantId')
|
||||
};
|
||||
},
|
||||
inject: [ConfigService]
|
||||
}),
|
||||
LogbookModule,
|
||||
PilotModule
|
||||
],
|
||||
controllers: [AppController],
|
||||
providers: [
|
||||
{
|
||||
provide: APP_GUARD,
|
||||
useClass: AuthGuard
|
||||
},
|
||||
{
|
||||
provide: APP_FILTER,
|
||||
useClass: HttpExceptionFilter
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { MsGraphService, MsGraphClient } from '@noahspan/noahspan-modules';
|
||||
// import { MsGraphService, MsGraphClient } from '@noahspan/noahspan-modules';
|
||||
import { Client as MsGraphClient } from '@microsoft/microsoft-graph-client';
|
||||
import { MsGraphService } from './msGraph/ms-graph.service';
|
||||
|
||||
@Injectable()
|
||||
export class AppService {
|
||||
constructor(private readonly msGraphService: MsGraphService) {}
|
||||
|
||||
getHello(): string {
|
||||
return 'Hello World!';
|
||||
return JSON.stringify(process.env);
|
||||
}
|
||||
|
||||
async getPersonSearchResults(
|
||||
|
||||
5
api/src/auth/auth.interface.ts
Normal file
5
api/src/auth/auth.interface.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export interface AuthModuleOptions {
|
||||
tenantId: string;
|
||||
clientId: string;
|
||||
clientSecret: string;
|
||||
}
|
||||
4
api/src/auth/auth.module-definition.ts
Normal file
4
api/src/auth/auth.module-definition.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { ConfigurableModuleBuilder } from '@nestjs/common';
|
||||
import { AuthModuleOptions } from './auth.interface';
|
||||
|
||||
export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } = new ConfigurableModuleBuilder<AuthModuleOptions>().build()
|
||||
14
api/src/auth/auth.module.ts
Normal file
14
api/src/auth/auth.module.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { PassportModule } from '@nestjs/passport';
|
||||
import { AzureAdStrategy } from './auth.strategy';
|
||||
import { ConfigurableModuleClass } from './auth.module-definition';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
PassportModule.register({
|
||||
defaultStrategy: 'azure-ad'
|
||||
})
|
||||
],
|
||||
providers: [AzureAdStrategy]
|
||||
})
|
||||
export class AuthModule extends ConfigurableModuleClass {}
|
||||
26
api/src/auth/auth.strategy.ts
Normal file
26
api/src/auth/auth.strategy.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { Inject, Injectable } from "@nestjs/common";
|
||||
import { PassportStrategy } from "@nestjs/passport";
|
||||
import { AuthModuleOptions } from './auth.interface'
|
||||
import { MODULE_OPTIONS_TOKEN } from "./auth.module-definition";
|
||||
import { BearerStrategy } from 'passport-azure-ad'
|
||||
|
||||
@Injectable()
|
||||
export class AzureAdStrategy extends PassportStrategy(
|
||||
BearerStrategy,
|
||||
'azure-ad'
|
||||
) {
|
||||
constructor(@Inject(MODULE_OPTIONS_TOKEN) authModuleOptions: AuthModuleOptions) {
|
||||
console.log(authModuleOptions)
|
||||
super({
|
||||
identityMetadata: `https://login.microsoftonline.com/${authModuleOptions.tenantId}/.well-known/openid-configuration`,
|
||||
clientID: authModuleOptions.clientId,
|
||||
audience: `api://${authModuleOptions.clientId}`,
|
||||
loggingLevel: 'info',
|
||||
loggingNoPII: false
|
||||
})
|
||||
}
|
||||
|
||||
async validate(data: any): Promise<any> {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
6
api/src/config/configuration.ts
Normal file
6
api/src/config/configuration.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export default () => ({
|
||||
azureStorageConnectionString: process.env.AZURE_STORAGE_CONNECTION_STRING,
|
||||
clientId: process.env.CLIENT_ID,
|
||||
clientSecret: process.env.CLIENT_SECRET,
|
||||
tenantId: process.env.TENANT_ID
|
||||
})
|
||||
@@ -6,4 +6,4 @@ export class CustomError extends Error {
|
||||
this.name = name;
|
||||
this.statusCode = statusCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
41
api/src/featureFlag/feature-flag.controller.ts
Normal file
41
api/src/featureFlag/feature-flag.controller.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
HttpException,
|
||||
Param,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { FeatureFlagService } from './feature-flag.service';
|
||||
import { CustomError } from '../error/customError';
|
||||
import { AuthGuard } from '@nestjs/passport';
|
||||
|
||||
@Controller('featureFlags')
|
||||
@UseGuards(AuthGuard('azure-ad'))
|
||||
export class FeatureFlagController {
|
||||
constructor(private readonly featureFlagService: FeatureFlagService) {}
|
||||
|
||||
@Get(':partitionKey/:rowKey')
|
||||
async find(
|
||||
@Param('partitionKey') partitionKey: string,
|
||||
@Param('rowKey') rowKey: string
|
||||
) {
|
||||
try {
|
||||
return await this.featureFlagService.find(partitionKey, rowKey);
|
||||
} catch (error) {
|
||||
const customError = error as CustomError;
|
||||
|
||||
throw new HttpException(customError.message, customError.statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
@Get()
|
||||
async findAll() {
|
||||
try {
|
||||
return await this.featureFlagService.findAll();
|
||||
} catch (error) {
|
||||
const customError = error as CustomError;
|
||||
|
||||
throw new HttpException(customError.message, customError.statusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
5
api/src/featureFlag/feature-flag.dto.ts
Normal file
5
api/src/featureFlag/feature-flag.dto.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export class FeatureFlagDto {
|
||||
partitionKey: string;
|
||||
rowKey: string;
|
||||
active: string;
|
||||
}
|
||||
7
api/src/featureFlag/feature-flag.entity.ts
Normal file
7
api/src/featureFlag/feature-flag.entity.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { EntityString } from '@noahspan/azure-database';
|
||||
|
||||
export class FeatureFlag {
|
||||
@EntityString() partitionKey: string;
|
||||
@EntityString() rowKey: string;
|
||||
@EntityString() active: string;
|
||||
}
|
||||
27
api/src/featureFlag/feature-flag.module.ts
Normal file
27
api/src/featureFlag/feature-flag.module.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { FeatureFlagController } from './feature-flag.controller';
|
||||
import { FeatureFlagService } from './feature-flag.service';
|
||||
import { AzureTableStorageModule } from '@noahspan/azure-database';
|
||||
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||
import { FeatureFlag } from './feature-flag.entity';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
AzureTableStorageModule.forRootAsync({
|
||||
imports: [ConfigModule],
|
||||
useFactory: async (configService: ConfigService) => {
|
||||
return {
|
||||
connectionString: configService.get<string>('azureStorageConnectionString')
|
||||
};
|
||||
},
|
||||
inject: [ConfigService]
|
||||
}),
|
||||
AzureTableStorageModule.forFeature(FeatureFlag, {
|
||||
createTableIfNotExists: false,
|
||||
table: 'featureFlags'
|
||||
}),
|
||||
],
|
||||
controllers: [FeatureFlagController],
|
||||
providers: [FeatureFlagService]
|
||||
})
|
||||
export class FeatureFlagModule {}
|
||||
18
api/src/featureFlag/feature-flag.service.ts
Normal file
18
api/src/featureFlag/feature-flag.service.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository, Repository } from '@noahspan/azure-database';
|
||||
import { FeatureFlag } from './feature-flag.entity';
|
||||
|
||||
@Injectable()
|
||||
export class FeatureFlagService {
|
||||
constructor(
|
||||
@InjectRepository(FeatureFlag) private readonly featureFlagRepository: Repository<FeatureFlag>
|
||||
) {}
|
||||
|
||||
async find(partitionKey: string, rowKey: string): Promise<FeatureFlag> {
|
||||
return await this.featureFlagRepository.find(partitionKey, rowKey);
|
||||
}
|
||||
|
||||
async findAll(): Promise<FeatureFlag[]> {
|
||||
return await this.featureFlagRepository.findAll();
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,6 @@ export class HttpExceptionFilter implements ExceptionFilter {
|
||||
const response = ctx.getResponse<Response>();
|
||||
const request = ctx.getRequest<Request>();
|
||||
const status = excpetion.getStatus();
|
||||
console.log(excpetion.cause);
|
||||
|
||||
response.status(status).json({
|
||||
name: excpetion.cause,
|
||||
|
||||
97
api/src/log/log.controller.ts
Normal file
97
api/src/log/log.controller.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Delete,
|
||||
Get,
|
||||
HttpException,
|
||||
Param,
|
||||
Post,
|
||||
Put,
|
||||
UseGuards
|
||||
} from '@nestjs/common';
|
||||
import { LogDto } from './log.dto';
|
||||
import { Log } from './log.entity';
|
||||
import { LogService } from './log.service';
|
||||
import { CustomError } from '../error/customError';
|
||||
import { AuthGuard } from '@nestjs/passport';
|
||||
|
||||
|
||||
@Controller('logs')
|
||||
@UseGuards(AuthGuard('azure-ad'))
|
||||
export class LogController {
|
||||
constructor(private readonly logService: LogService) {}
|
||||
|
||||
@Get(':partitionKey/:rowKey')
|
||||
async find(
|
||||
@Param('partitionKey') partitionKey: string,
|
||||
@Param('rowKey') rowKey: string
|
||||
): Promise<Log> {
|
||||
try {
|
||||
return await this.logService.find(partitionKey, rowKey);
|
||||
} catch (error) {
|
||||
const customError = error as CustomError;
|
||||
|
||||
throw new HttpException(customError.message, customError.statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
// @Public()
|
||||
@Get()
|
||||
async findAll(): Promise<Log[]> {
|
||||
try {
|
||||
return await this.logService.findAll();
|
||||
} catch (error) {
|
||||
const customError = error as CustomError;
|
||||
|
||||
throw new HttpException(customError.message, customError.statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
@Post()
|
||||
async create(@Body() logDto: LogDto): Promise<Log> {
|
||||
try {
|
||||
const log = new Log();
|
||||
|
||||
Object.assign(log, logDto);
|
||||
|
||||
return await this.logService.create(log);
|
||||
} catch (error) {
|
||||
const customError = error as CustomError;
|
||||
|
||||
throw new HttpException(customError.message, customError.statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
@Put(':partitionKey/:rowKey')
|
||||
async update(
|
||||
@Param('partitionKey') partitionKey: string,
|
||||
@Param('rowKey') rowKey: string,
|
||||
@Body() logDto: LogDto
|
||||
): Promise<Log> {
|
||||
try {
|
||||
const log = new Log();
|
||||
|
||||
Object.assign(log, logDto);
|
||||
|
||||
return await this.logService.update(partitionKey, rowKey, log);
|
||||
} catch (error) {
|
||||
const customError = error as CustomError;
|
||||
|
||||
throw new HttpException(customError.message, customError.statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
@Delete(':partitionKey/:rowKey')
|
||||
async delete(
|
||||
@Param('partitionKey') partitionKey: string,
|
||||
@Param('rowKey') rowKey: string
|
||||
): Promise<void> {
|
||||
try {
|
||||
return await this.logService.delete(partitionKey, rowKey);
|
||||
} catch (error) {
|
||||
const customError = error as CustomError;
|
||||
|
||||
throw new HttpException(customError.message, customError.statusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
export class LogbookDto {
|
||||
export class LogDto {
|
||||
pilotId: string;
|
||||
pilotName: string;
|
||||
date: string;
|
||||
@@ -1,4 +1,4 @@
|
||||
export class LogbookEntity {
|
||||
export class Log {
|
||||
partitionKey: string;
|
||||
rowKey: string;
|
||||
pilotId: string;
|
||||
27
api/src/log/log.module.ts
Normal file
27
api/src/log/log.module.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { LogController } from './log.controller';
|
||||
import { LogService } from './log.service';
|
||||
import { AzureTableStorageModule } from '@noahspan/azure-database';
|
||||
import { Log } from './log.entity';
|
||||
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
AzureTableStorageModule.forRootAsync({
|
||||
imports: [ConfigModule],
|
||||
useFactory: async (configService: ConfigService) => {
|
||||
return {
|
||||
connectionString: configService.get<string>('azureStorageConnectionString')
|
||||
};
|
||||
},
|
||||
inject: [ConfigService]
|
||||
}),
|
||||
AzureTableStorageModule.forFeature(Log, {
|
||||
createTableIfNotExists: false,
|
||||
table: 'logs'
|
||||
}),
|
||||
],
|
||||
controllers: [LogController],
|
||||
providers: [LogService]
|
||||
})
|
||||
export class LogModule {}
|
||||
34
api/src/log/log.service.ts
Normal file
34
api/src/log/log.service.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository, Repository } from '@noahspan/azure-database';
|
||||
import { Log } from './log.entity';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
@Injectable()
|
||||
export class LogService {
|
||||
constructor(
|
||||
@InjectRepository(Log) private readonly logRepository: Repository<Log>
|
||||
) {}
|
||||
|
||||
async find(partitionKey: string, rowKey: string): Promise<Log> {
|
||||
return await this.logRepository.find(partitionKey, rowKey);
|
||||
}
|
||||
|
||||
async findAll(): Promise<Log[]> {
|
||||
return await this.logRepository.findAll();
|
||||
}
|
||||
|
||||
async create(log: Log): Promise<Log> {
|
||||
log.partitionKey = 'log';
|
||||
log.rowKey = uuidv4();
|
||||
|
||||
return await this.logRepository.create(log);
|
||||
}
|
||||
|
||||
async update(partitionKey: string, rowKey: string, log: Log): Promise<Log> {
|
||||
return await this.logRepository.update(partitionKey, rowKey, log);
|
||||
}
|
||||
|
||||
async delete(partitionKey: string, rowKey: string): Promise<void> {
|
||||
await this.logRepository.delete(partitionKey, rowKey);
|
||||
}
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Delete,
|
||||
Get,
|
||||
HttpException,
|
||||
Param,
|
||||
Post,
|
||||
Put
|
||||
} from '@nestjs/common';
|
||||
import { LogbookService } from './logbook.service';
|
||||
import { LogbookDto } from './logbook.dto';
|
||||
import { CustomError } from '../customError/CustomError';
|
||||
import { TableInsertEntityHeaders } from '@azure/data-tables';
|
||||
import { LogbookEntity } from './logbook.entity';
|
||||
|
||||
@Controller('logbook')
|
||||
export class LogbookController {
|
||||
constructor(private readonly logbookService: LogbookService) {}
|
||||
|
||||
@Get(':entryId')
|
||||
async find(@Param() params: any): Promise<LogbookEntity> {
|
||||
try {
|
||||
const entry: LogbookEntity = await this.logbookService.find(
|
||||
params.entryId
|
||||
);
|
||||
|
||||
return entry;
|
||||
} catch (error) {
|
||||
const customError = error as CustomError;
|
||||
|
||||
throw new HttpException(customError.message, customError.statusCode, {
|
||||
cause: customError.name
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Get()
|
||||
async findAll(): Promise<LogbookEntity[]> {
|
||||
try {
|
||||
const logbookEntries: LogbookEntity[] =
|
||||
await this.logbookService.findAll();
|
||||
|
||||
return logbookEntries;
|
||||
} catch (error) {
|
||||
const customError = error as CustomError;
|
||||
|
||||
throw new HttpException(customError.message, customError.statusCode, {
|
||||
cause: customError.name
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Post()
|
||||
async create(@Body() logbookData: LogbookDto): Promise<void> {
|
||||
try {
|
||||
const response: TableInsertEntityHeaders =
|
||||
await this.logbookService.create(logbookData);
|
||||
} catch (error) {
|
||||
const customError = error as CustomError;
|
||||
|
||||
throw new HttpException(customError.message, customError.statusCode, {
|
||||
cause: customError.name
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Put(':entryId')
|
||||
async update(
|
||||
@Param() params: any,
|
||||
@Body() logbookData: LogbookDto
|
||||
): Promise<void> {
|
||||
try {
|
||||
return await this.logbookService.update(logbookData);
|
||||
} catch (error) {
|
||||
const customError = error as CustomError;
|
||||
|
||||
throw new HttpException(customError.message, customError.statusCode, {
|
||||
cause: customError.name
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Delete(':rowKey')
|
||||
async delete(@Param() params: any): Promise<void> {
|
||||
try {
|
||||
await this.logbookService.delete(params.rowKey);
|
||||
} catch (error) {
|
||||
const customError = error as CustomError;
|
||||
|
||||
throw new HttpException(customError.message, customError.statusCode, {
|
||||
cause: customError.name
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { LogbookController } from './logbook.controller';
|
||||
import { LogbookService } from './logbook.service';
|
||||
import { TableModule } from '@noahspan/noahspan-modules';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TableModule.register({
|
||||
accountName: process.env.AZURE_STORAGE_ACCOUNT_NAME,
|
||||
accountKey: process.env.AZURE_STORAGE_ACCOUNT_KEY,
|
||||
accountUrl: process.env.AZURE_STORAGE_ACCOUNT_URL,
|
||||
allowInsecureConnection: Boolean(
|
||||
process.env.AZURE_STORAGE_ALLOW_INSECURE_CONNECTION
|
||||
)
|
||||
})
|
||||
],
|
||||
controllers: [LogbookController],
|
||||
providers: [LogbookService]
|
||||
})
|
||||
export class LogbookModule {}
|
||||
@@ -1,183 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { TableClient, TableService } from '@noahspan/noahspan-modules';
|
||||
import { LogbookDto } from './logbook.dto';
|
||||
import { LogbookEntity } from './logbook.entity';
|
||||
import { RestError, TableInsertEntityHeaders } from '@azure/data-tables';
|
||||
import { CustomError } from '../customError/CustomError';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
@Injectable()
|
||||
export class LogbookService {
|
||||
private readonly tableName = 'Logbook';
|
||||
|
||||
constructor(private readonly tableService: TableService) {}
|
||||
|
||||
async getLogbookEntries(filter: string): Promise<LogbookEntity[]> {
|
||||
try {
|
||||
const client: TableClient = await this.tableService.getTableClient(
|
||||
this.tableName
|
||||
);
|
||||
const entities = await client.listEntities({
|
||||
queryOptions: { filter: filter }
|
||||
});
|
||||
const logbookEntries: LogbookEntity[] = [];
|
||||
|
||||
for await (const entity of entities) {
|
||||
const logbookEntry = {
|
||||
partitionKey: entity.partitionKey.toString(),
|
||||
rowKey: entity.rowKey.toString(),
|
||||
pilotId: entity.pilotId.toString(),
|
||||
pilotName: entity.pilotName.toString(),
|
||||
date: entity.date.toString(),
|
||||
aircraftMakeModel: entity.aircraftMakeModel.toString(),
|
||||
aircraftIdentity: entity.aircraftIdentity.toString(),
|
||||
routeFrom: entity.routeFrom.toString(),
|
||||
routeTo: entity.routeTo.toString(),
|
||||
durationOfFlight: Number(entity.durationOfFlight),
|
||||
singleEngineLand: entity.singleEngineLand
|
||||
? Number(entity.singleEngineLand)
|
||||
: null,
|
||||
simulatorAtd: entity.simulatorAtd
|
||||
? Number(entity.simulatorAtd)
|
||||
: null,
|
||||
landingsDay: entity.landingsDay ? Number(entity.landingsDay) : null,
|
||||
landingsNight: entity.landingsNight
|
||||
? Number(entity.landingsNight)
|
||||
: null,
|
||||
groundTrainingReceived: entity.groundTrainingReceived
|
||||
? Number(entity.groundTrainingReceived)
|
||||
: null,
|
||||
flightTrainingReceived: entity.flightTrainingReceived
|
||||
? Number(entity.flightTrainingReceived)
|
||||
: null,
|
||||
crossCountry: entity.crossCountry
|
||||
? Number(entity.crossCountry)
|
||||
: null,
|
||||
night: entity.night ? Number(entity.night) : null,
|
||||
solo: entity.solo ? Number(entity.solo) : null,
|
||||
pilotInCommand: entity.pilotInCommand
|
||||
? Number(entity.pilotInCommand)
|
||||
: null,
|
||||
instrumentActual: entity.instrumentActual
|
||||
? Number(entity.instrumentActual)
|
||||
: null,
|
||||
instrumentSimulated: entity.instrumentSimulated
|
||||
? Number(entity.instrumentSimulated)
|
||||
: null,
|
||||
instrumentApproaches: entity.instrumentApproaches
|
||||
? Number(entity.instrumentApproaches)
|
||||
: null,
|
||||
instrumentHolds: entity.instrumentHolds
|
||||
? Number(entity.instrumentHolds)
|
||||
: null,
|
||||
instrumentNavTrack: entity.instrumentNavTrack
|
||||
? Number(entity.instrumentNavTrack)
|
||||
: null,
|
||||
notes: entity.notes ? entity.notes.toString() : ''
|
||||
};
|
||||
|
||||
logbookEntries.push(logbookEntry);
|
||||
}
|
||||
|
||||
return logbookEntries;
|
||||
} catch (error) {
|
||||
const restError: RestError = error as RestError;
|
||||
|
||||
throw new CustomError(
|
||||
restError.details['odataError']['message']['value'],
|
||||
restError.details['odataError']['code'],
|
||||
restError.statusCode
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async find(entryId: string): Promise<LogbookEntity> {
|
||||
try {
|
||||
const filter: string = `PartitionKey eq 'entry' and RowKey eq '${entryId}'`;
|
||||
const entries: LogbookEntity[] = await this.getLogbookEntries(filter);
|
||||
|
||||
return entries[0];
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async findAll(): Promise<LogbookEntity[]> {
|
||||
try {
|
||||
const filter: string = `PartitionKey eq 'entry'`;
|
||||
const entries: LogbookEntity[] = await this.getLogbookEntries(filter);
|
||||
|
||||
return entries;
|
||||
} catch (error) {
|
||||
const restError: RestError = error as RestError;
|
||||
|
||||
throw new CustomError(
|
||||
restError.details['odataError']['message']['value'],
|
||||
restError.details['odataError']['code'],
|
||||
restError.statusCode
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async create(logbookData: LogbookDto): Promise<TableInsertEntityHeaders> {
|
||||
const client: TableClient = await this.tableService.getTableClient(
|
||||
this.tableName
|
||||
);
|
||||
const logbook: LogbookEntity = new LogbookEntity();
|
||||
|
||||
Object.assign(logbook, logbookData);
|
||||
logbook.partitionKey = 'entry';
|
||||
logbook.rowKey = uuidv4();
|
||||
|
||||
try {
|
||||
return await client.createEntity(logbook);
|
||||
} catch (error) {
|
||||
const restError: RestError = error as RestError;
|
||||
|
||||
throw new CustomError(
|
||||
restError.details['odataError']['message']['value'],
|
||||
restError.details['odataError']['code'],
|
||||
restError.statusCode
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async update(logbookData: LogbookDto): Promise<void> {
|
||||
try {
|
||||
const client: TableClient = await this.tableService.getTableClient(
|
||||
this.tableName
|
||||
);
|
||||
const logbook: LogbookEntity = new LogbookEntity();
|
||||
|
||||
Object.assign(logbook, logbookData);
|
||||
|
||||
await client.upsertEntity(logbook, 'Replace');
|
||||
} catch (error) {
|
||||
const restError: RestError = error as RestError;
|
||||
|
||||
throw new CustomError(
|
||||
restError.details['odataError']['message']['value'],
|
||||
restError.details['odataError']['code'],
|
||||
restError.statusCode
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async delete(rowKey: string): Promise<void> {
|
||||
try {
|
||||
const client: TableClient = await this.tableService.getTableClient(
|
||||
this.tableName
|
||||
);
|
||||
|
||||
await client.deleteEntity('entry', rowKey);
|
||||
} catch (error) {
|
||||
const restError: RestError = error as RestError;
|
||||
|
||||
throw new CustomError(
|
||||
restError.details['odataError']['message']['value'],
|
||||
restError.details['odataError']['code'],
|
||||
restError.statusCode
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import { INestApplication } from '@nestjs/common';
|
||||
import { NestFactory } from '@nestjs/core';
|
||||
import { AppModule } from './app.module';
|
||||
|
||||
export async function createApp(): Promise<INestApplication> {
|
||||
const app = await NestFactory.create(AppModule);
|
||||
app.setGlobalPrefix('api');
|
||||
|
||||
await app.init();
|
||||
return app;
|
||||
}
|
||||
@@ -3,13 +3,16 @@ import { AppModule } from './app.module';
|
||||
import { HttpService } from '@nestjs/axios';
|
||||
import { HttpExceptionFilter } from './filters/http-exception.filter';
|
||||
import { InternalServerErrorException } from '@nestjs/common';
|
||||
import { AuthGuard } from '@nestjs/passport';
|
||||
|
||||
async function bootstrap() {
|
||||
const httpService = new HttpService();
|
||||
const app = await NestFactory.create(AppModule);
|
||||
|
||||
app.enableCors();
|
||||
app.setGlobalPrefix('api');
|
||||
app.useGlobalFilters(new HttpExceptionFilter());
|
||||
|
||||
httpService.axiosRef.interceptors.response.use(
|
||||
(response) => {
|
||||
return response;
|
||||
@@ -20,6 +23,7 @@ async function bootstrap() {
|
||||
throw new InternalServerErrorException();
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
await app.listen(3000);
|
||||
}
|
||||
|
||||
5
api/src/msGraph/ms-graph.interface.ts
Normal file
5
api/src/msGraph/ms-graph.interface.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export interface MsGraphModuleOptions {
|
||||
tenantId: string;
|
||||
clientId: string;
|
||||
clientSecret: string;
|
||||
}
|
||||
4
api/src/msGraph/ms-graph.module-definition.ts
Normal file
4
api/src/msGraph/ms-graph.module-definition.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { ConfigurableModuleBuilder } from '@nestjs/common';
|
||||
import { MsGraphModuleOptions } from './ms-graph.interface';
|
||||
|
||||
export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } = new ConfigurableModuleBuilder<MsGraphModuleOptions>().build()
|
||||
9
api/src/msGraph/ms-graph.module.ts
Normal file
9
api/src/msGraph/ms-graph.module.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { MsGraphService } from './ms-graph.service';
|
||||
import { ConfigurableModuleClass } from './ms-graph.module-definition';
|
||||
|
||||
@Module({
|
||||
providers: [MsGraphService],
|
||||
exports: [MsGraphService]
|
||||
})
|
||||
export class MsGraphModule extends ConfigurableModuleClass {}
|
||||
41
api/src/msGraph/ms-graph.service.ts
Normal file
41
api/src/msGraph/ms-graph.service.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { MsGraphModuleOptions } from './ms-graph.interface';
|
||||
import { Client } from '@microsoft/microsoft-graph-client';
|
||||
import { AuthenticationResult, ConfidentialClientApplication, OnBehalfOfRequest } from '@azure/msal-node';
|
||||
import { MODULE_OPTIONS_TOKEN } from './ms-graph.module-definition';
|
||||
|
||||
@Injectable()
|
||||
export class MsGraphService {
|
||||
constructor(@Inject(MODULE_OPTIONS_TOKEN) private msGraphModuleOptions: MsGraphModuleOptions) {}
|
||||
|
||||
async getMsGraphAuth(accessToken: string, scopes: string[]): Promise<string> {
|
||||
try {
|
||||
const oboRequest: OnBehalfOfRequest = {
|
||||
oboAssertion: accessToken,
|
||||
scopes: scopes
|
||||
}
|
||||
const cca = new ConfidentialClientApplication({
|
||||
auth: {
|
||||
clientId: this.msGraphModuleOptions.clientId,
|
||||
clientSecret: this.msGraphModuleOptions.clientSecret,
|
||||
authority: `https://login.microsoftonline.com/${this.msGraphModuleOptions.tenantId}`
|
||||
}
|
||||
});
|
||||
const authenticationResult: AuthenticationResult = await cca.acquireTokenOnBehalfOf(oboRequest);
|
||||
|
||||
return authenticationResult.accessToken
|
||||
} catch (error) {
|
||||
return error
|
||||
}
|
||||
}
|
||||
|
||||
async getMsGraphClientDelegated(accessToken): Promise<Client> {
|
||||
const client = await Client.init({
|
||||
authProvider: (done) => {
|
||||
done(null, accessToken);
|
||||
}
|
||||
});
|
||||
|
||||
return client;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Repository, InjectRepository } from '@nestjs/azure-database';
|
||||
import { Repository, InjectRepository } from '@noahspan/azure-database';
|
||||
import { Certificate } from './certificate.entity';
|
||||
|
||||
@Injectable()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { InjectRepository, Repository } from '@nestjs/azure-database';
|
||||
import { InjectRepository, Repository } from '@noahspan/azure-database';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Endorsement } from './endorsement.entity';
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
export class PilotInfoEntity {
|
||||
partitionKey: string;
|
||||
rowKey: string;
|
||||
id: string;
|
||||
name: string;
|
||||
address?: string;
|
||||
city?: string;
|
||||
state?: string;
|
||||
postalCode?: string;
|
||||
email?: string;
|
||||
phone?: string;
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { PilotInfoDto } from './pilot-info.dto';
|
||||
import { PilotInfoEntity } from './pilot-info.entity';
|
||||
import { TableClient, TableService } from '@noahspan/noahspan-modules';
|
||||
import { odata, RestError, TableInsertEntityHeaders } from '@azure/data-tables';
|
||||
import { CustomError } from '../../customError/CustomError';
|
||||
|
||||
@Injectable()
|
||||
export class PilotInfoService {
|
||||
private readonly partitionKey: string = 'info';
|
||||
|
||||
constructor(private readonly tableService: TableService) {}
|
||||
|
||||
async find(pilotId: string): Promise<PilotInfoEntity> {
|
||||
try {
|
||||
const client: TableClient =
|
||||
await this.tableService.getTableClient('Pilots');
|
||||
const entities = await client.listEntities({
|
||||
queryOptions: {
|
||||
filter: odata`PartitionKey eq 'pilot' and RowKey eq '${pilotId}'`
|
||||
}
|
||||
});
|
||||
let pilot: PilotInfoEntity;
|
||||
console.log(entities);
|
||||
for await (const entity of entities) {
|
||||
pilot = {
|
||||
partitionKey: entity.partitionKey,
|
||||
rowKey: entity.rowKey,
|
||||
id: entity.id.toString(),
|
||||
name: entity.name.toString(),
|
||||
address: entity.address.toString(),
|
||||
city: entity.city.toString(),
|
||||
state: entity.state.toString(),
|
||||
postalCode: entity.postalCode.toString(),
|
||||
email: entity.email.toString(),
|
||||
phone: entity.phone.toString()
|
||||
};
|
||||
}
|
||||
|
||||
return pilot;
|
||||
} catch (error) {
|
||||
const restError: RestError = error as RestError;
|
||||
|
||||
throw new CustomError(
|
||||
restError.details['odataError']['message']['value'],
|
||||
restError.details['odataError']['code'],
|
||||
restError.statusCode
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async findAll(): Promise<PilotInfoEntity[]> {
|
||||
try {
|
||||
const client: TableClient =
|
||||
await this.tableService.getTableClient('Pilots');
|
||||
const entities = await client.listEntities({
|
||||
queryOptions: { filter: odata`PartitionKey eq 'pilot'` }
|
||||
});
|
||||
const pilots: PilotInfoEntity[] = [];
|
||||
|
||||
for await (const entity of entities) {
|
||||
const pilot: PilotInfoEntity = {
|
||||
partitionKey: entity.partitionKey,
|
||||
rowKey: entity.rowKey,
|
||||
id: entity.id.toString(),
|
||||
name: entity.name.toString()
|
||||
};
|
||||
|
||||
pilots.push(pilot);
|
||||
}
|
||||
|
||||
return pilots;
|
||||
} catch (error) {
|
||||
const restError: RestError = error as RestError;
|
||||
|
||||
throw new CustomError(
|
||||
restError.details['odataError']['message']['value'],
|
||||
restError.details['odataError']['code'],
|
||||
restError.statusCode
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async create(pilotInfoData: PilotInfoDto): Promise<TableInsertEntityHeaders> {
|
||||
try {
|
||||
const client: TableClient =
|
||||
await this.tableService.getTableClient('Pilots');
|
||||
const pilotInfo: PilotInfoEntity = new PilotInfoEntity();
|
||||
|
||||
Object.assign(pilotInfo, pilotInfoData);
|
||||
pilotInfo.partitionKey = 'pilot';
|
||||
pilotInfo.rowKey = pilotInfo.id;
|
||||
console.log(pilotInfo);
|
||||
return await client.createEntity(pilotInfo);
|
||||
} catch (error) {
|
||||
const restError: RestError = error as RestError;
|
||||
console.log(restError);
|
||||
throw new CustomError(
|
||||
restError.details['odataError']['message']['value'],
|
||||
restError.details['odataError']['code'],
|
||||
restError.statusCode
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// async update(rowKey: string, pilotInfo: PilotInfo): Promise<PilotInfo> {
|
||||
// return await this.pilotInfoRepository.update(
|
||||
// this.partitionKey,
|
||||
// rowKey,
|
||||
// pilotInfo
|
||||
// );
|
||||
// }
|
||||
|
||||
// async delete(rowKey: string): Promise<void> {
|
||||
// await this.pilotInfoRepository.delete(this.partitionKey, rowKey);
|
||||
// }
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Repository, InjectRepository } from '@nestjs/azure-database';
|
||||
import { Repository, InjectRepository } from '@noahspan/azure-database';
|
||||
import { Medical } from './medical.entity';
|
||||
|
||||
@Injectable()
|
||||
|
||||
@@ -1,71 +1,95 @@
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Delete,
|
||||
Get,
|
||||
HttpException,
|
||||
Param,
|
||||
Post,
|
||||
UseInterceptors
|
||||
Put,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { PilotInfoService } from './info/pilot-info.service';
|
||||
import { PilotInfoDto } from './info/pilot-info.dto';
|
||||
import { TableInsertEntityHeaders } from '@azure/data-tables';
|
||||
import { CustomError } from '../customError/CustomError';
|
||||
import { PilotInfoEntity } from './info/pilot-info.entity';
|
||||
import { PilotInterceptor } from 'src/pilot/interceptors/pilot.interceptor';
|
||||
import { Public } from '@noahspan/noahspan-modules';
|
||||
import { PilotDto } from './pilot.dto';
|
||||
import { Pilot } from './pilot.entity';
|
||||
import { PilotService } from './pilot.service';
|
||||
import { CustomError } from '../error/customError';
|
||||
import { AuthGuard } from '@nestjs/passport'
|
||||
|
||||
@Controller('pilots')
|
||||
@UseGuards(AuthGuard('azure-ad'))
|
||||
export class PilotController {
|
||||
constructor(private readonly pilotInfoService: PilotInfoService) {}
|
||||
constructor(private readonly pilotService: PilotService) {}
|
||||
|
||||
@Get(':pilotId')
|
||||
@Public()
|
||||
@UseInterceptors(PilotInterceptor)
|
||||
async find(@Param() params: any): Promise<PilotInfoEntity> {
|
||||
@Get(':partitionKey/:rowKey')
|
||||
async find(
|
||||
@Param('partitionKey') partitionKey: string,
|
||||
@Param('rowKey') rowKey: string
|
||||
) {
|
||||
try {
|
||||
const pilot: PilotInfoEntity = await this.pilotInfoService.find(
|
||||
params.pilotId
|
||||
);
|
||||
|
||||
return pilot;
|
||||
return await this.pilotService.find(partitionKey, rowKey);
|
||||
} catch (error) {
|
||||
const customError = error as CustomError;
|
||||
|
||||
throw new HttpException(customError.message, customError.statusCode, {
|
||||
cause: customError.name
|
||||
});
|
||||
throw new HttpException(customError.message, customError.statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
@Get()
|
||||
@Public()
|
||||
@UseInterceptors(PilotInterceptor)
|
||||
async findAll(): Promise<PilotInfoEntity[]> {
|
||||
async findAll() {
|
||||
try {
|
||||
const pilots: PilotInfoEntity[] = await this.pilotInfoService.findAll();
|
||||
|
||||
return pilots;
|
||||
return await this.pilotService.findAll();
|
||||
} catch (error) {
|
||||
const customError = error as CustomError;
|
||||
|
||||
throw new HttpException(customError.message, customError.statusCode, {
|
||||
cause: customError.name
|
||||
});
|
||||
throw new HttpException(customError.message, customError.statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
@Post()
|
||||
async create(@Body() pilotInfoData: PilotInfoDto): Promise<void> {
|
||||
async create(@Body() pilotDto: PilotDto) {
|
||||
try {
|
||||
const response: TableInsertEntityHeaders =
|
||||
await this.pilotInfoService.create(pilotInfoData);
|
||||
const pilot = new Pilot();
|
||||
|
||||
Object.assign(pilot, pilotDto);
|
||||
|
||||
return await this.pilotService.create(pilot);
|
||||
} catch (error) {
|
||||
const customError = error as CustomError;
|
||||
|
||||
throw new HttpException(customError.message, customError.statusCode, {
|
||||
cause: customError.name
|
||||
});
|
||||
throw new HttpException(customError.message, customError.statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
@Put(':partitionKey/:rowKey')
|
||||
async update(
|
||||
@Param('partitionKey') partitionKey: string,
|
||||
@Param('rowKey') rowKey: string,
|
||||
@Body() pilotDto: PilotDto
|
||||
) {
|
||||
try {
|
||||
const pilot = new Pilot();
|
||||
|
||||
Object.assign(pilot, pilotDto);
|
||||
|
||||
return await this.pilotService.update(partitionKey, rowKey, pilot);
|
||||
} catch (error) {
|
||||
const customError = error as CustomError;
|
||||
|
||||
throw new HttpException(customError.message, customError.statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
@Delete(':partitionKey/:rowKey')
|
||||
async delete(
|
||||
@Param('partitionKey') partitionKey: string,
|
||||
@Param('rowKey') rowKey: string
|
||||
) {
|
||||
try {
|
||||
return await this.pilotService.delete(partitionKey, rowKey);
|
||||
} catch (error) {
|
||||
const customError = error as CustomError;
|
||||
|
||||
throw new HttpException(customError.message, customError.statusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export class PilotInfoDto {
|
||||
export class PilotDto {
|
||||
partitionKey: string;
|
||||
rowKey: string;
|
||||
id: string;
|
||||
name: string;
|
||||
address: string;
|
||||
14
api/src/pilot/pilot.entity.ts
Normal file
14
api/src/pilot/pilot.entity.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { EntityString } from '@noahspan/azure-database';
|
||||
|
||||
export class Pilot {
|
||||
@EntityString() partitionKey: string;
|
||||
@EntityString() rowKey: string;
|
||||
@EntityString() id: string;
|
||||
@EntityString() name: string;
|
||||
@EntityString() address?: string;
|
||||
@EntityString() city?: string;
|
||||
@EntityString() state?: string;
|
||||
@EntityString() postalCode?: string;
|
||||
@EntityString() email?: string;
|
||||
@EntityString() phone?: string;
|
||||
}
|
||||
@@ -1,20 +1,27 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { PilotController } from './pilot.controller';
|
||||
import { TableModule } from '@noahspan/noahspan-modules';
|
||||
import { PilotInfoService } from './info/pilot-info.service';
|
||||
import { PilotService } from './pilot.service';
|
||||
import { AzureTableStorageModule } from '@noahspan/azure-database';
|
||||
import { Pilot } from './pilot.entity';
|
||||
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TableModule.register({
|
||||
accountName: process.env.AZURE_STORAGE_ACCOUNT_NAME,
|
||||
accountKey: process.env.AZURE_STORAGE_ACCOUNT_KEY,
|
||||
accountUrl: process.env.AZURE_STORAGE_ACCOUNT_URL,
|
||||
allowInsecureConnection: Boolean(
|
||||
process.env.AZURE_STORAGE_ALLOW_INSECURE_CONNECTION
|
||||
)
|
||||
})
|
||||
AzureTableStorageModule.forRootAsync({
|
||||
imports: [ConfigModule],
|
||||
useFactory: async (configService: ConfigService) => {
|
||||
return {
|
||||
connectionString: configService.get<string>('azureStorageConnectionString')
|
||||
};
|
||||
},
|
||||
inject: [ConfigService]
|
||||
}),
|
||||
AzureTableStorageModule.forFeature(Pilot, {
|
||||
createTableIfNotExists: false,
|
||||
table: 'pilots'
|
||||
}),
|
||||
],
|
||||
controllers: [PilotController],
|
||||
providers: [PilotInfoService]
|
||||
providers: [PilotService]
|
||||
})
|
||||
export class PilotModule {}
|
||||
|
||||
40
api/src/pilot/pilot.service.ts
Normal file
40
api/src/pilot/pilot.service.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { InjectRepository, Repository } from '@noahspan/azure-database';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Pilot } from './pilot.entity';
|
||||
|
||||
@Injectable()
|
||||
export class PilotService {
|
||||
constructor(
|
||||
@InjectRepository(Pilot)
|
||||
private readonly pilotRepository: Repository<Pilot>
|
||||
) {}
|
||||
|
||||
async find(partitionKey: string, rowKey: string): Promise<Pilot> {
|
||||
return await this.pilotRepository.find(partitionKey, rowKey);
|
||||
}
|
||||
|
||||
async findAll(): Promise<Pilot[]> {
|
||||
return await this.pilotRepository.findAll();
|
||||
}
|
||||
|
||||
async create(pilot: Pilot): Promise<Pilot> {
|
||||
// try {
|
||||
// return await this.pilotRepository.create(pilot);
|
||||
// } catch (error) {
|
||||
// throw new Error(error);
|
||||
// }
|
||||
return await this.pilotRepository.create(pilot);
|
||||
}
|
||||
|
||||
async update(
|
||||
partitionKey: string,
|
||||
rowKey: string,
|
||||
pilot: Pilot
|
||||
): Promise<Pilot> {
|
||||
return await this.pilotRepository.update(partitionKey, rowKey, pilot);
|
||||
}
|
||||
|
||||
async delete(partitionKey: string, rowKey: string): Promise<void> {
|
||||
await this.pilotRepository.delete(partitionKey, rowKey);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user