diff --git a/docker-compose.yml b/docker-compose.yml index 1d593f26d9..087b9815fd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -17,6 +17,7 @@ services: restart: unless-stopped ibf-api-service: + container_name: ibf-api-service build: context: ./services/API-service args: @@ -88,6 +89,7 @@ services: web-server-network: ibf-geoserver: + container_name: ibf-geoserver image: kartoza/geoserver:2.19.2 environment: - GEOSERVER_ADMIN_PASSWORD=${GEOSERVER_ADMIN_PASSWORD} diff --git a/services/API-service/src/scripts/json/countries.json b/services/API-service/src/scripts/json/countries.json index 57b1d2b33d..e96b8887b8 100644 --- a/services/API-service/src/scripts/json/countries.json +++ b/services/API-service/src/scripts/json/countries.json @@ -9,7 +9,15 @@ "disasterType": "floods", "adminLevels": [2, 3, 4], "defaultAdminLevel": 2, - "activeLeadTimes": ["5-day"], + "activeLeadTimes": [ + "1-day", + "2-day", + "3-day", + "4-day", + "5-day", + "6-day", + "7-day" + ], "eapLink": "https://docs.google.com/document/d/1z4KfTIF1aJKgx-te8gPY6Scr2FcYR51x/edit#bookmark=id.j5clfgl1ywrd", "eapAlertClasses": { "no": { diff --git a/services/API-service/src/scripts/mock-data/floods/UGA/trigger/G5075/upload-alert_threshold-2.json b/services/API-service/src/scripts/mock-data/floods/UGA/trigger/G5075/upload-alert_threshold-2.json new file mode 100644 index 0000000000..12bb44117f --- /dev/null +++ b/services/API-service/src/scripts/mock-data/floods/UGA/trigger/G5075/upload-alert_threshold-2.json @@ -0,0 +1,34 @@ +[ + { + "placeCode": "21UGA003004", + "amount": 0.3 + }, + { + "placeCode": "21UGA003005", + "amount": 0.3 + }, + { + "placeCode": "21UGA003006", + "amount": 0.3 + }, + { + "placeCode": "21UGA003007", + "amount": 0.3 + }, + { + "placeCode": "21UGA005001", + "amount": 0.3 + }, + { + "placeCode": "21UGA005003", + "amount": 0.3 + }, + { + "placeCode": "21UGA005006", + "amount": 0.3 + }, + { + "placeCode": "21UGA005011", + "amount": 0.3 + } +] diff --git a/services/API-service/src/scripts/mock-data/floods/UGA/trigger/G5075/upload-population_affected-2.json b/services/API-service/src/scripts/mock-data/floods/UGA/trigger/G5075/upload-population_affected-2.json new file mode 100644 index 0000000000..6e674108da --- /dev/null +++ b/services/API-service/src/scripts/mock-data/floods/UGA/trigger/G5075/upload-population_affected-2.json @@ -0,0 +1,34 @@ +[ + { + "placeCode": "21UGA003004", + "amount": null + }, + { + "placeCode": "21UGA003005", + "amount": null + }, + { + "placeCode": "21UGA003006", + "amount": null + }, + { + "placeCode": "21UGA003007", + "amount": null + }, + { + "placeCode": "21UGA005001", + "amount": null + }, + { + "placeCode": "21UGA005003", + "amount": null + }, + { + "placeCode": "21UGA005006", + "amount": null + }, + { + "placeCode": "21UGA005011", + "amount": null + } +] diff --git a/services/API-service/src/scripts/mock-data/floods/UGA/trigger/G5220/upload-alert_threshold-2.json b/services/API-service/src/scripts/mock-data/floods/UGA/trigger/G5220/upload-alert_threshold-2.json new file mode 100644 index 0000000000..b5cbf92008 --- /dev/null +++ b/services/API-service/src/scripts/mock-data/floods/UGA/trigger/G5220/upload-alert_threshold-2.json @@ -0,0 +1,26 @@ +[ + { + "placeCode": "21UGA003001", + "amount": 1 + }, + { + "placeCode": "21UGA003003", + "amount": 1 + }, + { + "placeCode": "21UGA006001", + "amount": 1 + }, + { + "placeCode": "21UGA006006", + "amount": 1 + }, + { + "placeCode": "21UGA006007", + "amount": 1 + }, + { + "placeCode": "21UGA006008", + "amount": 1 + } +] diff --git a/services/API-service/src/scripts/mock-data/floods/UGA/trigger/G5220/upload-population_affected-2.json b/services/API-service/src/scripts/mock-data/floods/UGA/trigger/G5220/upload-population_affected-2.json new file mode 100644 index 0000000000..3a02d24b1f --- /dev/null +++ b/services/API-service/src/scripts/mock-data/floods/UGA/trigger/G5220/upload-population_affected-2.json @@ -0,0 +1,26 @@ +[ + { + "placeCode": "21UGA003001", + "amount": 17845 + }, + { + "placeCode": "21UGA003003", + "amount": 114286 + }, + { + "placeCode": "21UGA006001", + "amount": 2145 + }, + { + "placeCode": "21UGA006006", + "amount": 2201 + }, + { + "placeCode": "21UGA006007", + "amount": 8123 + }, + { + "placeCode": "21UGA006008", + "amount": 3380 + } +] diff --git a/services/API-service/src/scripts/mock-data/floods/UGA/trigger/G5230/upload-alert_threshold-2.json b/services/API-service/src/scripts/mock-data/floods/UGA/trigger/G5230/upload-alert_threshold-2.json new file mode 100644 index 0000000000..b7b2deccfe --- /dev/null +++ b/services/API-service/src/scripts/mock-data/floods/UGA/trigger/G5230/upload-alert_threshold-2.json @@ -0,0 +1,10 @@ +[ + { + "placeCode": "21UGA003002", + "amount": 0.7 + }, + { + "placeCode": "21UGA005010", + "amount": 0.7 + } +] diff --git a/services/API-service/src/scripts/mock-data/floods/UGA/trigger/G5230/upload-population_affected-2.json b/services/API-service/src/scripts/mock-data/floods/UGA/trigger/G5230/upload-population_affected-2.json new file mode 100644 index 0000000000..2d3aaeb217 --- /dev/null +++ b/services/API-service/src/scripts/mock-data/floods/UGA/trigger/G5230/upload-population_affected-2.json @@ -0,0 +1,10 @@ +[ + { + "placeCode": "21UGA003002", + "amount": null + }, + { + "placeCode": "21UGA005010", + "amount": null + } +] diff --git a/services/API-service/src/scripts/scripts.controller.ts b/services/API-service/src/scripts/scripts.controller.ts index c44540d54c..3e2f7943a8 100644 --- a/services/API-service/src/scripts/scripts.controller.ts +++ b/services/API-service/src/scripts/scripts.controller.ts @@ -85,6 +85,10 @@ export enum TyphoonScenario { EventAfterLandfall = 'eventAfterLandfall', } +export enum FloodsScenario { + Trigger = 'trigger', +} + export class MockTyphoonScenario { @ApiProperty({ example: 'fill_in_secret' }) @IsNotEmpty() @@ -114,6 +118,31 @@ export class MockTyphoonScenario { public readonly date: Date; } +export class MockFloodsScenario { + @ApiProperty({ example: 'fill_in_secret' }) + @IsNotEmpty() + @IsString() + public readonly secret: string; + + @ApiProperty({ example: 'UGA' }) + @IsIn(['UGA']) + public readonly countryCodeISO3: string; + + @ApiProperty({ + example: Object.values(FloodsScenario).join(' | '), + }) + @IsEnum(FloodsScenario) + public readonly scenario: FloodsScenario; + + @ApiProperty({ example: true }) + @IsNotEmpty() + public readonly removeEvents: boolean; + + @ApiProperty({ example: new Date() }) + @IsOptional() + public readonly date: Date; +} + @Controller('scripts') @ApiTags('--- mock/seed data ---') @ApiBearerAuth() @@ -207,4 +236,26 @@ export class ScriptsController { return res.status(HttpStatus.ACCEPTED).send(result); } + + @Roles(UserRole.Admin) + @ApiOperation({ + summary: 'Upload mock data for specific floods scenario', + }) + @ApiResponse({ + status: 202, + description: 'Uploaded mock data for specific floods scenario', + }) + @Post('/mock-floods-scenario') + public async mockFloodsScenario( + @Body() body: MockFloodsScenario, + @Res() res, + ): Promise { + if (body.secret !== process.env.RESET_SECRET) { + return res.status(HttpStatus.FORBIDDEN).send('Not allowed'); + } + + const result = await this.scriptsService.mockFloodsScenario(body); + + return res.status(HttpStatus.ACCEPTED).send(result); + } } diff --git a/services/API-service/src/scripts/scripts.service.ts b/services/API-service/src/scripts/scripts.service.ts index 42d350f894..e3610a9bdd 100644 --- a/services/API-service/src/scripts/scripts.service.ts +++ b/services/API-service/src/scripts/scripts.service.ts @@ -3,8 +3,10 @@ import { AdminAreaDynamicDataService } from '../api/admin-area-dynamic-data/admi import { DisasterType } from '../api/disaster/disaster-type.enum'; import { GlofasStationService } from '../api/glofas-station/glofas-station.service'; import { + FloodsScenario, MockAll, MockDynamic, + MockFloodsScenario, MockTyphoonScenario, TyphoonScenario, } from './scripts.controller'; @@ -277,6 +279,74 @@ export class ScriptsService { } } + public async mockFloodsScenario(mockFloodsScenario: MockFloodsScenario) { + console.log('mockFloodsScenario: ', mockFloodsScenario); + if (mockFloodsScenario.scenario === FloodsScenario.Trigger) { + // 1. API-call: /exposure + // per event/leadTime (some events could have same leadTime) + const events = [ + { eventName: 'G5220', leadTime: '2-day' }, + { eventName: 'G5075', leadTime: '4-day' }, + { eventName: 'G5230', leadTime: '6-day' }, + ]; + for (const event of events) { + // per admin-level? + const adminLevels = [2]; // [2, 3, 4]; simplify for now + for (const adminLevel of adminLevels) { + // per indicator + // TODO: get indicators from metadata-service + const indicators = ['alert_threshold', 'population_affected']; + for (const indicator of indicators) { + // TODO: get from json mock data files + const exposurePlaceCodes = this.getEventMockData( + DisasterType.Floods, + mockFloodsScenario.countryCodeISO3, + mockFloodsScenario.scenario, + event.eventName, + adminLevel, + indicator as DynamicIndicator, + ); + + await this.adminAreaDynamicDataService.exposure({ + countryCodeISO3: mockFloodsScenario.countryCodeISO3, + exposurePlaceCodes, + leadTime: event.leadTime as LeadTime, + dynamicIndicator: indicator as DynamicIndicator, + adminLevel: adminLevel as AdminLevel, + disasterType: DisasterType.Floods, + eventName: event.eventName, + date: mockFloodsScenario.date || new Date(), + }); + } + } + } + + // 2. API-call: /trigger-per-lead-time (or forget about for now?) + + // 3. API-call: /glofas-stations + + // 4. API-call: /raster-file + + // 5. API-call: map-image-file? (not for now) + } else { + // TODO: other scenarios + } + } + + private getEventMockData( + disasterType: DisasterType, + countryCodeISO3: string, + scenario: string, + eventName: string, + adminLevel: AdminLevel, + indicator: DynamicIndicator, + ) { + const fileName = `upload-${indicator}-${adminLevel}`; + const exposureFileName = `./src/scripts/mock-data/${disasterType}/${countryCodeISO3}/${scenario}/${eventName}/${fileName}.json`; + const exposureRaw = fs.readFileSync(exposureFileName, 'utf-8'); + return JSON.parse(exposureRaw); + } + private async mockExposure( selectedCountry, disasterType: DisasterType, @@ -404,7 +474,7 @@ export class ScriptsService { eventNr: number, countryCodeISO3: string, disasterType: DisasterType, - triggered: boolean, + triggered = true, typhoonScenario?: TyphoonScenario, ) { let fileName = `upload-${unit}-${adminLevel}`;