switching to sqlite
This commit is contained in:
3
api/.gitignore
vendored
3
api/.gitignore
vendored
@@ -57,3 +57,6 @@ report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
|
||||
local.settings.json
|
||||
|
||||
|
||||
/src/database/*.db
|
||||
|
||||
3
api/entrypoint.sh
Normal file
3
api/entrypoint.sh
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
npx typeorm migration:run -d ./dist/config/typeorm-cli.config.js
|
||||
node ./dist/main.js
|
||||
@@ -17,7 +17,7 @@
|
||||
"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",
|
||||
"typeorm": "npm run build && npx typeorm -d dist/config/typeorm-cli.config.js",
|
||||
"typeorm": "npm run build && npx typeorm -d dist/database/data-source.js",
|
||||
"migration:generate": "npm run typeorm -- migration:generate",
|
||||
"migration:run": "npm run typeorm -- migration:run",
|
||||
"migration:revert": "npm run typeorm -- migration:revert"
|
||||
@@ -25,21 +25,29 @@
|
||||
"dependencies": {
|
||||
"@azure/storage-blob": "^12.27.0",
|
||||
"@microsoft/microsoft-graph-client": "^3.0.7",
|
||||
"@nestjs/axios": "^3.0.3",
|
||||
"@nestjs/common": "^10.0.0",
|
||||
"@nestjs/config": "^3.2.2",
|
||||
"@nestjs/core": "^10.0.0",
|
||||
"@nestjs/passport": "^10.0.3",
|
||||
"@nestjs/platform-express": "^10.0.0",
|
||||
"@nestjs/axios": "^4.0.1",
|
||||
"@nestjs/common": "^11.1.6",
|
||||
"@nestjs/config": "^4.0.2",
|
||||
"@nestjs/core": "^11.1.6",
|
||||
"@nestjs/jwt": "^11.0.0",
|
||||
"@nestjs/passport": "^11.0.5",
|
||||
"@nestjs/platform-express": "^11.1.6",
|
||||
"@nestjs/serve-static": "^5.0.3",
|
||||
"@nestjs/typeorm": "^11.0.0",
|
||||
"@noahspan/azure-database": "^3.1.2",
|
||||
"@noahspan/noahspan-modules": "^1.1.5",
|
||||
"@noahspan/noahspan-modules": "^1.2.8",
|
||||
"@schematics/angular": "^17.3.7",
|
||||
"@types/multer": "^1.4.12",
|
||||
"better-sqlite3": "^12.2.0",
|
||||
"dotenv": "^16.6.1",
|
||||
"express-session": "^1.18.2",
|
||||
"jwks-rsa": "^3.2.0",
|
||||
"node-gyp": "^11.4.1",
|
||||
"passport": "^0.7.0",
|
||||
"passport-jwt": "^4.0.1",
|
||||
"passport-openidconnect": "^0.1.2",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"rxjs": "^7.8.1",
|
||||
"sqlite3": "^5.1.7",
|
||||
"typeorm": "^0.3.25",
|
||||
"uuid": "^10.0.0",
|
||||
"uuidv4": "^6.2.13"
|
||||
@@ -48,11 +56,13 @@
|
||||
"@microsoft/microsoft-graph-types": "^2.40.0",
|
||||
"@nestjs/cli": "^10.0.0",
|
||||
"@nestjs/schematics": "^10.0.0",
|
||||
"@nestjs/testing": "^10.0.0",
|
||||
"@nestjs/testing": "^11.1.6",
|
||||
"@types/express": "^4.17.17",
|
||||
"@types/express-session": "^1.18.2",
|
||||
"@types/jest": "^29.5.2",
|
||||
"@types/node": "^20.3.1",
|
||||
"@types/passport-azure-ad": "^4.3.6",
|
||||
"@types/passport-openidconnect": "^0.1.3",
|
||||
"@types/supertest": "^6.0.0",
|
||||
"jest": "^29.5.0",
|
||||
"source-map-support": "^0.5.21",
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
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!');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,15 +1,17 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { FeatureFlagModule } from './featureFlag/feature-flag.module'
|
||||
import { HealthModule } from './health/health.module';
|
||||
import { LogModule } from './log/log.module';
|
||||
import { PilotModule } from './pilot/pilot.module';
|
||||
import { APP_FILTER, APP_GUARD, Reflector } from '@nestjs/core';
|
||||
import { HttpExceptionFilter } from './filters/http-exception.filter';
|
||||
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||
import { AuthGuard, AuthModule, UserModule } from '@noahspan/noahspan-modules';
|
||||
import { AuthModule, MsGraphModule } from '@noahspan/noahspan-modules';
|
||||
import configuration from './config/configuration';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { dataSourceOptions } from './config/typeorm-cli.config';
|
||||
import { dataSourceOptions } from './database/data-source';
|
||||
import { TrackModule } from './track/track.module';
|
||||
import { ServeStaticModule } from '@nestjs/serve-static';
|
||||
import { join } from 'path';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -18,9 +20,9 @@ import { TrackModule } from './track/track.module';
|
||||
imports: [ConfigModule],
|
||||
useFactory: async (configService: ConfigService) => {
|
||||
return {
|
||||
clientId: configService.get<string>('clientId'),
|
||||
clientSecret: configService.get<string>('clientSecret'),
|
||||
tenantId: configService.get<string>('tenantId')
|
||||
audience: configService.get<string>('audience'),
|
||||
issuerUrl: configService.get<string>('issuer'),
|
||||
jwksUri: configService.get<string>('jwksUri')
|
||||
};
|
||||
},
|
||||
}),
|
||||
@@ -28,12 +30,15 @@ import { TrackModule } from './track/track.module';
|
||||
isGlobal: true,
|
||||
load: [configuration]
|
||||
}),
|
||||
FeatureFlagModule,
|
||||
LogModule,
|
||||
// HealthModule,
|
||||
// LogModule,
|
||||
PilotModule,
|
||||
TrackModule,
|
||||
ServeStaticModule.forRoot({
|
||||
rootPath: join(__dirname, '../..', 'client', 'dist')
|
||||
}),
|
||||
// TrackModule,
|
||||
TypeOrmModule.forRoot(dataSourceOptions),
|
||||
UserModule.registerAsync({
|
||||
MsGraphModule.registerAsync({
|
||||
inject: [ConfigService],
|
||||
imports: [ConfigModule],
|
||||
useFactory: async (configService: ConfigService) => {
|
||||
@@ -49,7 +54,7 @@ import { TrackModule } from './track/track.module';
|
||||
{
|
||||
provide: APP_FILTER,
|
||||
useClass: HttpExceptionFilter
|
||||
},
|
||||
}
|
||||
]
|
||||
})
|
||||
export class AppModule {}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
export interface AuthModuleOptions {
|
||||
tenantId: string;
|
||||
clientId: string;
|
||||
clientSecret: string;
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
import { ConfigurableModuleBuilder } from '@nestjs/common';
|
||||
import { AuthModuleOptions } from './auth.interface';
|
||||
|
||||
export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } = new ConfigurableModuleBuilder<AuthModuleOptions>().build()
|
||||
@@ -1,14 +0,0 @@
|
||||
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 {}
|
||||
@@ -1,25 +0,0 @@
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
export default () => ({
|
||||
azureStorageConnectionString: process.env.AZURE_STORAGE_CONNECTION_STRING,
|
||||
audience: process.env.AUDIENCE,
|
||||
clientId: process.env.CLIENT_ID,
|
||||
clientSecret: process.env.CLIENT_SECRET,
|
||||
issuer: process.env.ISSUER_URL,
|
||||
jwksUri: process.env.JWKS_URI,
|
||||
tenantId: process.env.TENANT_ID
|
||||
})
|
||||
@@ -1,17 +1,16 @@
|
||||
import { DataSource, DataSourceOptions } from 'typeorm';
|
||||
import { config } from 'dotenv';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import configuration from './configuration';
|
||||
|
||||
config();
|
||||
|
||||
const configService = new ConfigService();
|
||||
|
||||
export const dataSourceOptions: DataSourceOptions = {
|
||||
type: 'sqlite',
|
||||
type: 'better-sqlite3',
|
||||
database: configService.get<string>('DB_PATH'),
|
||||
entities: ['dist/**/*.entity.js'],
|
||||
migrations: ['dist/migrations/*.js'],
|
||||
migrations: ['dist/database/migrations/*.js'],
|
||||
synchronize: configService.get<boolean>('DB_SYNC')
|
||||
}
|
||||
|
||||
4
api/src/database/litestream.yml
Normal file
4
api/src/database/litestream.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
dbs:
|
||||
- path: /var/lib/data/flying.db
|
||||
replicas:
|
||||
- path: /mnt/data/backup
|
||||
@@ -1,13 +1,13 @@
|
||||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
export class InitialMigration1754234179211 implements MigrationInterface {
|
||||
name = 'InitialMigration1754234179211'
|
||||
export class InitialMigration1758802917932 implements MigrationInterface {
|
||||
name = 'InitialMigration1758802917932'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`CREATE TABLE "certificates" ("id" varchar PRIMARY KEY NOT NULL, "type" varchar NOT NULL, "number" varchar NOT NULL, "issueDate" datetime NOT NULL, "pilotId" varchar)`);
|
||||
await queryRunner.query(`CREATE TABLE "endorsements" ("id" varchar PRIMARY KEY NOT NULL, "type" varchar NOT NULL, "issueDate" datetime NOT NULL, "pilotId" varchar)`);
|
||||
await queryRunner.query(`CREATE TABLE "medical" ("id" varchar PRIMARY KEY NOT NULL, "class" varchar NOT NULL, "expirationDate" datetime NOT NULL, "pilotId" varchar)`);
|
||||
await queryRunner.query(`CREATE TABLE "pilots" ("id" varchar PRIMARY KEY NOT NULL, "name" varchar NOT NULL, "address" varchar NOT NULL, "city" varchar NOT NULL, "state" varchar NOT NULL, "postalCode" varchar NOT NULL, "email" varchar NOT NULL, "phone" varchar NOT NULL)`);
|
||||
await queryRunner.query(`CREATE TABLE "pilots" ("id" varchar PRIMARY KEY NOT NULL, "name" varchar NOT NULL, "address" varchar NOT NULL, "city" varchar NOT NULL, "state" varchar NOT NULL, "postalCode" varchar NOT NULL, "email" varchar NOT NULL, "phone" varchar NOT NULL, "userId" varchar NOT NULL)`);
|
||||
await queryRunner.query(`CREATE TABLE "logs" ("id" varchar PRIMARY KEY NOT NULL, "date" datetime NOT NULL, "aircraftMakeModel" varchar NOT NULL, "aircraftIdentity" varchar NOT NULL, "routeFrom" varchar NOT NULL, "routeTo" varchar NOT NULL, "durationOfFlight" integer NOT NULL, "singleEngineLand" integer, "simulatorAtd" integer, "landingsDay" integer, "landingsNight" integer, "groundTrainingReceived" integer, "flightTrainingReceived" integer, "crossCountry" integer, "night" integer, "solo" integer, "pilotInCommand" integer, "instrumentActual" integer, "instrumentSimulated" integer, "instrumentApproaches" integer, "instrumentHolds" integer, "instrumentNavTrack" integer, "notes" varchar, "pilotId" varchar)`);
|
||||
await queryRunner.query(`CREATE TABLE "tracks" ("id" varchar PRIMARY KEY NOT NULL, "url" varchar NOT NULL, "order" integer NOT NULL, "logId" varchar)`);
|
||||
await queryRunner.query(`CREATE TABLE "temporary_certificates" ("id" varchar PRIMARY KEY NOT NULL, "type" varchar NOT NULL, "number" varchar NOT NULL, "issueDate" datetime NOT NULL, "pilotId" varchar, CONSTRAINT "FK_05a68997dc2d27dfcc642a4cf51" FOREIGN KEY ("pilotId") REFERENCES "pilots" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
|
||||
@@ -1,41 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
export class FeatureFlagDto {
|
||||
partitionKey: string;
|
||||
rowKey: string;
|
||||
active: string;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import { EntityString } from '@noahspan/azure-database';
|
||||
|
||||
export class FeatureFlag {
|
||||
@EntityString() partitionKey: string;
|
||||
@EntityString() rowKey: string;
|
||||
@EntityString() active: string;
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
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 {}
|
||||
@@ -1,18 +0,0 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
42
api/src/health/health.controller.spec.ts
Normal file
42
api/src/health/health.controller.spec.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { HealthController } from './health.controller';
|
||||
import { HealthService } from './health.service';
|
||||
|
||||
describe('HealthController', () => {
|
||||
let controller; HealthController;
|
||||
|
||||
const mockHealthService = {
|
||||
isDatabaseConnected: jest.fn()
|
||||
}
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [HealthController],
|
||||
providers: [HealthService]
|
||||
}).compile();
|
||||
|
||||
controller = module.get<HealthController>(HealthController);
|
||||
})
|
||||
|
||||
it('isHealthy => should return true', () => {
|
||||
expect(controller).toBeDefined();
|
||||
});
|
||||
|
||||
it('should return database connected', async () => {
|
||||
jest.spyOn(mockHealthService, 'isDatabaseConnected').mockReturnValue(true);
|
||||
|
||||
const result = await controller.isHealthy();
|
||||
|
||||
expect(mockHealthService.isDatabaseConnected).toHaveBeenCalled();
|
||||
expect(result).toEqual(true);
|
||||
})
|
||||
|
||||
it('isHealthy => should return error', async () => {
|
||||
jest.spyOn(mockHealthService, 'isDatabaseConnected').mockReturnValue(false);
|
||||
|
||||
const result = await controller.isHealthy();
|
||||
|
||||
expect(mockHealthService.isDatabaseConnected).toHaveBeenCalled();
|
||||
expect(result).toEqual(false);
|
||||
})
|
||||
})
|
||||
27
api/src/health/health.controller.ts
Normal file
27
api/src/health/health.controller.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
HttpException,
|
||||
} from '@nestjs/common';
|
||||
import { HealthService } from './health.service';
|
||||
import { CustomError } from 'src/error/customError';
|
||||
|
||||
|
||||
@Controller('health')
|
||||
export class HealthController {
|
||||
constructor(
|
||||
private readonly healthService: HealthService
|
||||
) {}
|
||||
|
||||
|
||||
@Get()
|
||||
async isHealthy(): Promise<boolean> {
|
||||
try {
|
||||
return await this.healthService.isDatabaseConnected();
|
||||
} catch (error) {
|
||||
const customError = error as CustomError;
|
||||
|
||||
throw new HttpException(customError.message, customError.statusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
api/src/health/health.module.ts
Normal file
11
api/src/health/health.module.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { HealthController } from './health.controller';
|
||||
import { HealthService } from './health.service';
|
||||
|
||||
@Module({
|
||||
controllers: [HealthController],
|
||||
providers: [
|
||||
HealthService
|
||||
]
|
||||
})
|
||||
export class HealthModule {}
|
||||
14
api/src/health/health.service.spec.ts
Normal file
14
api/src/health/health.service.spec.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { HealthService } from './health.service';
|
||||
|
||||
describe('HealthService', () => {
|
||||
let service: HealthService;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [HealthService]
|
||||
}).compile();
|
||||
|
||||
service = module.get<HealthService>(HealthService);
|
||||
});
|
||||
});
|
||||
22
api/src/health/health.service.ts
Normal file
22
api/src/health/health.service.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { CustomError } from '../error/customError';
|
||||
import { DataSource } from 'typeorm';
|
||||
|
||||
@Injectable()
|
||||
export class HealthService {
|
||||
constructor(private dataSource: DataSource) {}
|
||||
|
||||
async isDatabaseConnected(): Promise<boolean> {
|
||||
try {
|
||||
const isDatabaseConnected: boolean = this.dataSource.isInitialized;
|
||||
|
||||
if (isDatabaseConnected) {
|
||||
return isDatabaseConnected;
|
||||
} else {
|
||||
throw new CustomError('Database not connected', 'Database not connected', 400)
|
||||
}
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +1,3 @@
|
||||
// export class Log {
|
||||
// partitionKey: string;
|
||||
// rowKey: string;
|
||||
// pilotId: string;
|
||||
// pilotName: string;
|
||||
// date: string;
|
||||
// aircraftMakeModel: string;
|
||||
// aircraftIdentity: string;
|
||||
// routeFrom: string;
|
||||
// routeTo: string;
|
||||
// durationOfFlight: number | null;
|
||||
// singleEngineLand: number | null;
|
||||
// simulatorAtd?: number | null;
|
||||
// landingsDay?: number | null;
|
||||
// landingsNight?: number | null;
|
||||
// groundTrainingReceived?: number;
|
||||
// flightTrainingReceived?: number;
|
||||
// crossCountry?: number | null;
|
||||
// night?: number | null;
|
||||
// solo?: number | null;
|
||||
// pilotInCommand?: number | null;
|
||||
// instrumentActual?: number | null;
|
||||
// instrumentSimulated?: number | null;
|
||||
// instrumentApproaches?: number | null;
|
||||
// instrumentHolds?: number | null;
|
||||
// instrumentNavTrack?: number | null;
|
||||
// tracks?: string[];
|
||||
// notes?: string;
|
||||
// }
|
||||
|
||||
import { PilotEntity } from 'src/pilot/pilot.entity';
|
||||
import { TrackEntity } from 'src/track/track.entity';
|
||||
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn, OneToMany } from 'typeorm';
|
||||
|
||||
@@ -3,15 +3,26 @@ 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';
|
||||
import * as session from 'express-session';
|
||||
|
||||
async function bootstrap() {
|
||||
const httpService = new HttpService();
|
||||
const app = await NestFactory.create(AppModule);
|
||||
|
||||
app.enableCors();
|
||||
app.enableCors({
|
||||
origin: 'http://localhost:8080', // Allow requests from your frontend's origin
|
||||
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
|
||||
credentials: true, // If you need to send cookies or authorization headers
|
||||
});
|
||||
app.setGlobalPrefix('api');
|
||||
app.useGlobalFilters(new HttpExceptionFilter());
|
||||
app.use(
|
||||
session({
|
||||
secret: 'blah',
|
||||
resave: false,
|
||||
saveUninitialized: false
|
||||
})
|
||||
)
|
||||
|
||||
httpService.axiosRef.interceptors.response.use(
|
||||
(response) => {
|
||||
|
||||
@@ -14,8 +14,8 @@ import { PilotDto } from './pilot.dto';
|
||||
import { PilotEntity } from './pilot.entity';
|
||||
import { PilotService } from './pilot.service';
|
||||
import { CustomError } from '../error/customError';
|
||||
import { AuthGuard } from '@noahspan/noahspan-modules'
|
||||
import { PilotInterceptor } from './interceptors/pilot.interceptor';
|
||||
import { AuthGuard } from '@noahspan/noahspan-modules';
|
||||
|
||||
@Controller('pilots')
|
||||
// @UseInterceptors(new PilotInterceptor())
|
||||
@@ -34,6 +34,7 @@ export class PilotController {
|
||||
}
|
||||
|
||||
@Get()
|
||||
@UseGuards(AuthGuard)
|
||||
async findAll() {
|
||||
try {
|
||||
return await this.pilotService.findAll();
|
||||
@@ -44,7 +45,7 @@ export class PilotController {
|
||||
}
|
||||
}
|
||||
|
||||
// @UseGuards(AuthGuard)
|
||||
@UseGuards(AuthGuard)
|
||||
@Post()
|
||||
async create(@Body() pilotDto: PilotDto) {
|
||||
try {
|
||||
|
||||
@@ -1,22 +1,3 @@
|
||||
// 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;
|
||||
// @EntityString() medicalClass?: string;
|
||||
// @EntityString() medicalExpiration: string;
|
||||
// @EntityString() certificates: string;
|
||||
// @EntityString() endorsements: string;
|
||||
// }
|
||||
|
||||
import { LogEntity } from 'src/log/log.entity';
|
||||
import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm';
|
||||
import { CertificateEntity } from '../certificate/certificate.entity';
|
||||
@@ -49,6 +30,9 @@ export class PilotEntity {
|
||||
@Column()
|
||||
phone: string;
|
||||
|
||||
@Column()
|
||||
userId: string | null;
|
||||
|
||||
@OneToMany(() => LogEntity, (log: LogEntity) => log.pilot, {onDelete: 'CASCADE', onUpdate: 'CASCADE'})
|
||||
logs: LogEntity[];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user