From 0da17195a14fa5735e5430f8ffbcff91a5299cba Mon Sep 17 00:00:00 2001 From: Pratiksharai-Rumsan Date: Wed, 3 Dec 2025 14:41:12 +0545 Subject: [PATCH 1/3] add mock-api --- apps/mock-api/.env.example | 13 + apps/mock-api/.gitignore | 56 + apps/mock-api/.prettierrc | 4 + apps/mock-api/Dockerfile | 49 + apps/mock-api/README.md | 183 + apps/mock-api/eslint.config.mjs | 5 + apps/mock-api/nest-cli.json | 10 + apps/mock-api/package.json | 73 + apps/mock-api/src/all-exceptions.filter.ts | 38 + apps/mock-api/src/app.controller.ts | 23 + apps/mock-api/src/app.module.ts | 30 + apps/mock-api/src/app.service.ts | 8 + apps/mock-api/src/common/index.ts | 270 + apps/mock-api/src/constants/datasourceUrls.ts | 18 + apps/mock-api/src/data/dhm/index.ts | 35 + apps/mock-api/src/data/gfh/index.ts | 9591 +++++++++++++++++ apps/mock-api/src/data/glofas/raw-response.ts | 1030 ++ .../src/forecast/forecast.controller.ts | 43 + apps/mock-api/src/forecast/forecast.module.ts | 11 + .../mock-api/src/forecast/forecast.service.ts | 164 + apps/mock-api/src/helpers/wiston.logger.ts | 52 + apps/mock-api/src/main.ts | 52 + apps/mock-api/src/triggers/dto/trigger.dto.ts | 34 + apps/mock-api/src/triggers/trigger.module.ts | 10 + apps/mock-api/src/triggers/trigger.service.ts | 87 + .../src/triggers/triggers.controller.ts | 52 + apps/mock-api/src/types/data-source.ts | 243 + apps/mock-api/src/utils/date.ts | 18 + apps/mock-api/tsconfig.build.json | 4 + apps/mock-api/tsconfig.json | 11 + packages/database/.env.example | 2 - .../migration.sql | 20 - .../migration.sql | 384 + packages/database/prisma/schema/mock.prisma | 2 +- pnpm-lock.yaml | 169 +- 35 files changed, 12748 insertions(+), 46 deletions(-) create mode 100644 apps/mock-api/.env.example create mode 100644 apps/mock-api/.gitignore create mode 100644 apps/mock-api/.prettierrc create mode 100644 apps/mock-api/Dockerfile create mode 100644 apps/mock-api/README.md create mode 100644 apps/mock-api/eslint.config.mjs create mode 100644 apps/mock-api/nest-cli.json create mode 100644 apps/mock-api/package.json create mode 100644 apps/mock-api/src/all-exceptions.filter.ts create mode 100644 apps/mock-api/src/app.controller.ts create mode 100644 apps/mock-api/src/app.module.ts create mode 100644 apps/mock-api/src/app.service.ts create mode 100644 apps/mock-api/src/common/index.ts create mode 100644 apps/mock-api/src/constants/datasourceUrls.ts create mode 100644 apps/mock-api/src/data/dhm/index.ts create mode 100644 apps/mock-api/src/data/gfh/index.ts create mode 100644 apps/mock-api/src/data/glofas/raw-response.ts create mode 100644 apps/mock-api/src/forecast/forecast.controller.ts create mode 100644 apps/mock-api/src/forecast/forecast.module.ts create mode 100644 apps/mock-api/src/forecast/forecast.service.ts create mode 100644 apps/mock-api/src/helpers/wiston.logger.ts create mode 100644 apps/mock-api/src/main.ts create mode 100644 apps/mock-api/src/triggers/dto/trigger.dto.ts create mode 100644 apps/mock-api/src/triggers/trigger.module.ts create mode 100644 apps/mock-api/src/triggers/trigger.service.ts create mode 100644 apps/mock-api/src/triggers/triggers.controller.ts create mode 100644 apps/mock-api/src/types/data-source.ts create mode 100644 apps/mock-api/src/utils/date.ts create mode 100644 apps/mock-api/tsconfig.build.json create mode 100644 apps/mock-api/tsconfig.json delete mode 100644 packages/database/prisma/schema/migrations/20251128051042_add_schema_for_mock_forecast/migration.sql create mode 100644 packages/database/prisma/schema/migrations/20251203082405_add_mock_api_database/migration.sql diff --git a/apps/mock-api/.env.example b/apps/mock-api/.env.example new file mode 100644 index 0000000..d9e9d81 --- /dev/null +++ b/apps/mock-api/.env.example @@ -0,0 +1,13 @@ +# Database Configuration +DB_HOST=localhost +DB_PORT=5432 +DB_USER=postgres +DB_PASSWORD=postgres +DB_NAME=rahat_triggers + +# Application Configuration +PORT=8000 +NODE_ENV=development + +# Optional: You can also set DATABASE_URL directly if you prefer +# DATABASE_URL=postgresql://postgres:postgres@localhost:5432/rahat_triggers diff --git a/apps/mock-api/.gitignore b/apps/mock-api/.gitignore new file mode 100644 index 0000000..4b56acf --- /dev/null +++ b/apps/mock-api/.gitignore @@ -0,0 +1,56 @@ +# compiled output +/dist +/node_modules +/build + +# Logs +logs +*.log +npm-debug.log* +pnpm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# OS +.DS_Store + +# Tests +/coverage +/.nyc_output + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# temp directory +.temp +.tmp + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json diff --git a/apps/mock-api/.prettierrc b/apps/mock-api/.prettierrc new file mode 100644 index 0000000..dcb7279 --- /dev/null +++ b/apps/mock-api/.prettierrc @@ -0,0 +1,4 @@ +{ + "singleQuote": true, + "trailingComma": "all" +} \ No newline at end of file diff --git a/apps/mock-api/Dockerfile b/apps/mock-api/Dockerfile new file mode 100644 index 0000000..5bf512d --- /dev/null +++ b/apps/mock-api/Dockerfile @@ -0,0 +1,49 @@ +FROM node:20-alpine AS base + +# The web Dockerfile is copy-pasted into our main docs at /docs/handbook/deploying-with-docker. +# Make sure you update this Dockerfile, the Dockerfile in the web workspace and copy that over to Dockerfile in the docs. + +FROM base AS builder +# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. +RUN apk update +RUN apk add --no-cache libc6-compat openssl +# Set working directory +WORKDIR /app +RUN npm install -g turbo +COPY . . +RUN turbo prune api --docker + +# Add lockfile and package.json's of isolated subworkspace +FROM base AS installer +RUN apk update +RUN apk add --no-cache libc6-compat openssl +RUN npm install -g pnpm@8.14.1 +WORKDIR /app + + +# First install dependencies (as they change less often) +COPY --from=builder /app/out/json/ . +RUN pnpm install +COPY --from=builder /app/out/full/ . +RUN pnpm turbo build + +# Clean up unnecessary files to reduce image size +RUN rm -rf node_modules +RUN find apps/api -type f -not -path 'apps/api/dist/*' -not -name 'package.json' -delete && rm -rf apps/api/test apps/api/src +RUN pnpm install --prod && pnpm store prune + + +FROM base AS runner +WORKDIR /app + +# Create log directory and set permissions +RUN mkdir -p /app/.log && chmod -R 777 /app/.log +# Don't run production as root +RUN addgroup --system --gid 1001 nestjs +RUN adduser --system --uid 1001 nestjs +USER nestjs +COPY --from=installer /app . +# Tag the final image +LABEL stage="final" +RUN docker rmi $(docker images -f "label=stage=intermediate" -q) || true +CMD node apps/api/dist/main.js diff --git a/apps/mock-api/README.md b/apps/mock-api/README.md new file mode 100644 index 0000000..59f467f --- /dev/null +++ b/apps/mock-api/README.md @@ -0,0 +1,183 @@ +# NestJs API Seed + +The application is NestJS API Seed. This application provides RESTful APIs for managing operations and integrates with the shared database package for data persistence. + +## Overview + +The API application is built with NestJS and provides a robust API layer for handling various trigger operations. It includes comprehensive error handling, logging, API documentation, and database integration through the shared database package. + +## Features + +- **RESTful API**: Well-structured REST endpoints for trigger operations +- **Database Integration**: Uses the shared `@lib/database` package for data operations +- **Exception Handling**: Global exception filters for database and application errors +- **API Documentation**: Auto-generated Swagger documentation +- **Logging**: Structured logging with Winston integration +- **Validation**: Request validation using class-validator +- **CORS Support**: Cross-origin resource sharing enabled +- **Development Tools**: Hot reload and debugging support + +## Project Structure + +``` +src/ +├── app.controller.ts # Main application controller +├── app.module.ts # Root application module +├── app.service.ts # Main application service +├── main.ts # Application bootstrap file +├── all-exceptions.filter.ts # Global exception filter +├── helpers/ +│ └── winston.logger.ts # Winston logger configuration +└── source-data/ + ├── source-data.controller.ts # Source data API endpoints + ├── source-data.module.ts # Source data module + └── source-data.service.ts # Source data business logic +``` + +## Environment Configuration + +The application requires environment variables to be configured. Copy the example file and update the values: + +```bash +cp .env.example .env +``` + +The application supports both direct DATABASE_URL configuration and individual database parameters. See the `.env.example` file for all available configuration options. + +## Available Scripts + +### Development + +```bash +# Start in development mode with hot reload +pnpm dev + +# Start in debug mode +pnpm start:debug + +# Build the application +pnpm build + +# Start in production mode +pnpm start:prod +``` + +### Testing + +```bash +# Run unit tests +pnpm test + +# Run tests in watch mode +pnpm test:watch + +# Run end-to-end tests +pnpm test:e2e + +# Generate test coverage report +pnpm test:cov +``` + +### Code Quality + +```bash +# Run ESLint +pnpm lint + +# Format code with Prettier +pnpm format +``` + +## API Endpoints + +The application provides the following main endpoints: + +### Health Check + +- `GET /v1` - Basic health check endpoint +- `GET /v1/health` - Detailed health status + +## API Documentation + +When the application is running, you can access the interactive Swagger documentation at: + +``` +http://localhost:3000/swagger +``` + +The Swagger UI provides detailed information about all available endpoints, request/response schemas, and allows you to test the API directly from the browser. + +## Database Integration + +The application uses the shared `@lib/database` package which provides: + +- **Prisma ORM Integration**: Type-safe database operations +- **Connection Management**: Automatic database connection handling +- **Exception Handling**: Comprehensive error handling for database operations +- **Migration Support**: Database schema migrations + +The database configuration is handled automatically through environment variables, supporting both direct DATABASE_URL and individual connection parameters. + +## Error Handling + +The application includes comprehensive error handling: + +- **Global Exception Filter**: Catches and formats all unhandled exceptions +- **Prisma Exception Filter**: Specifically handles database-related errors +- **Validation Errors**: Automatic validation of request data +- **Structured Error Responses**: Consistent error response format + +## Logging + +The application uses Winston for structured logging with different log levels: + +- **Development**: Detailed logs with query information +- **Production**: Optimized logging for performance +- **Error Tracking**: Comprehensive error logging with context + +## Development Workflow + +1. **Start the database**: Ensure PostgreSQL is running +2. **Set up environment**: Configure your `.env` file +3. **Install dependencies**: Run `pnpm install` from the root +4. **Generate Prisma client**: Run `pnpm --filter @lib/database db:generate` +5. **Run migrations**: Run `pnpm --filter @lib/database db:migrate` +6. **Start development server**: Run `pnpm dev` + +## Configuration + +The application can be configured through environment variables: + +- **Database Configuration**: Connection details for PostgreSQL +- **Application Settings**: Port, environment mode, etc. +- **Logging Configuration**: Log levels and output formats + +## Troubleshooting + +### Common Issues + +1. **Port Already in Use**: Change the PORT environment variable +2. **Database Connection Failed**: Verify database configuration and ensure PostgreSQL is running +3. **Build Errors**: Clear node_modules and reinstall dependencies +4. **Migration Issues**: Check database permissions and connection string + +### Debug Mode + +To run the application in debug mode: + +```bash +pnpm start:debug +``` + +This enables the Node.js debugger and provides detailed logging for troubleshooting issues. + +## Production Deployment + +For production deployment: + +1. Set `NODE_ENV=production` in your environment +2. Configure production database settings +3. Build the application: `pnpm build` +4. Start with: `pnpm start:prod` + +The application includes production-optimized logging and error handling when running in production mode. diff --git a/apps/mock-api/eslint.config.mjs b/apps/mock-api/eslint.config.mjs new file mode 100644 index 0000000..a769a25 --- /dev/null +++ b/apps/mock-api/eslint.config.mjs @@ -0,0 +1,5 @@ +/** @type {import("eslint").Linter.Config[]} */ + +import { nestjs } from '@workspace/eslint-config/nest-js'; + +export default [...nestjs]; diff --git a/apps/mock-api/nest-cli.json b/apps/mock-api/nest-cli.json new file mode 100644 index 0000000..40a752e --- /dev/null +++ b/apps/mock-api/nest-cli.json @@ -0,0 +1,10 @@ +{ + "$schema": "https://json.schemastore.org/nest-cli", + "collection": "@nestjs/schematics", + "sourceRoot": "src", + "compilerOptions": { + "deleteOutDir": true, + "assets": [], + "watchAssets": false + } +} \ No newline at end of file diff --git a/apps/mock-api/package.json b/apps/mock-api/package.json new file mode 100644 index 0000000..7f4808c --- /dev/null +++ b/apps/mock-api/package.json @@ -0,0 +1,73 @@ +{ + "name": "mock-api", + "version": "0.0.1", + "description": "Nestjs API Seed", + "author": "Dipesh Kumar Sah", + "private": true, + "license": "UNLICENSED", + "module": "commonjs", + "scripts": { + "build": "nest build", + "format": "prettier --write \"src/**/*.ts\"", + "start": "nest start", + "start:dev": "nest start --watch", + "dev": "nest start --watch", + "dev:debug": "nest start --watch --debug", + "start:debug": "nest start --debug --watch", + "start:prod": "node dist/main", + "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", + "test": "jest", + "test:watch": "jest --watch", + "test:cov": "jest --coverage", + "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", + "test:e2e": "jest --config ./test/jest-e2e.json" + }, + "dependencies": { + "@lib/core": "workspace:*", + "@lib/database": "workspace:*", + "@lib/dhm-adapter": "workspace:*", + "@lib/glofas-adapter": "workspace:*", + "@nestjs/platform-express": "^10.3.7", + "cheerio": "^1.1.2", + "expr-eval": "^2.0.2", + "luxon": "^3.7.2", + "reflect-metadata": "^0.1.13", + "rxjs": "^7.8.1" + }, + "devDependencies": { + "@nestjs/cli": "^10.0.0", + "@nestjs/schematics": "^10.0.0", + "@nestjs/testing": "^10.0.1", + "@swc/cli": "^0.6.0", + "@swc/core": "^1.10.7", + "@types/express": "^4.17.17", + "@types/jest": "^29.5.14", + "@types/node": "^20.3.1", + "@types/supertest": "^6.0.2", + "@workspace/eslint-config": "workspace:*", + "@workspace/typescript-config": "workspace:*", + "jest": "^29.7.0", + "source-map-support": "^0.5.21", + "supertest": "^7.0.0", + "ts-jest": "^29.2.5", + "tsconfig-paths": "^4.2.0" + }, + "packageManager": "pnpm@8.14.1", + "jest": { + "moduleFileExtensions": [ + "js", + "json", + "ts" + ], + "rootDir": "src", + "testRegex": ".*\\.spec\\.ts$", + "transform": { + "^.+\\.(t|j)s$": "ts-jest" + }, + "collectCoverageFrom": [ + "**/*.(t|j)s" + ], + "coverageDirectory": "../coverage", + "testEnvironment": "node" + } +} diff --git a/apps/mock-api/src/all-exceptions.filter.ts b/apps/mock-api/src/all-exceptions.filter.ts new file mode 100644 index 0000000..ac8e232 --- /dev/null +++ b/apps/mock-api/src/all-exceptions.filter.ts @@ -0,0 +1,38 @@ +import { + ExceptionFilter, + Catch, + ArgumentsHost, + HttpException, + HttpStatus, +} from '@nestjs/common'; +import { Request, Response } from 'express'; + +@Catch() +export class AllExceptionsFilter implements ExceptionFilter { + catch(exception: unknown, host: ArgumentsHost) { + const ctx = host.switchToHttp(); + const response = ctx.getResponse(); + const request = ctx.getRequest(); + + let status = HttpStatus.INTERNAL_SERVER_ERROR; + let message = 'Internal server error'; + + if (exception instanceof HttpException) { + status = exception.getStatus(); + const exceptionResponse = exception.getResponse(); + message = + typeof exceptionResponse === 'string' + ? exceptionResponse + : (exceptionResponse as any).message || message; + } else if (exception instanceof Error) { + message = exception.message; + } + + response.status(status).json({ + statusCode: status, + timestamp: new Date().toISOString(), + path: request.url, + message, + }); + } +} diff --git a/apps/mock-api/src/app.controller.ts b/apps/mock-api/src/app.controller.ts new file mode 100644 index 0000000..59a0949 --- /dev/null +++ b/apps/mock-api/src/app.controller.ts @@ -0,0 +1,23 @@ +import { Controller, Get } from '@nestjs/common'; +import { AppService } from './app.service'; + +@Controller() +export class AppController { + constructor(private readonly appService: AppService) {} + + @Get() + getHello(): { message: string; result: number } { + return { + message: 'Hello from Rahat Triggers API!', + result: 1 + 2, + }; + } + + @Get('health') + getHealth(): { status: string; timestamp: string } { + return { + status: 'OK', + timestamp: new Date().toISOString(), + }; + } +} diff --git a/apps/mock-api/src/app.module.ts b/apps/mock-api/src/app.module.ts new file mode 100644 index 0000000..fd63038 --- /dev/null +++ b/apps/mock-api/src/app.module.ts @@ -0,0 +1,30 @@ +import { Module } from '@nestjs/common'; +import { AppController } from './app.controller'; +import { AppService } from './app.service'; +import { PrismaModule } from '@lib/database'; +// import { DhmModule } from '@lib/dhm-adapter'; +import { ConfigModule } from '@nestjs/config'; +import { HttpModule } from '@nestjs/axios'; +import { SettingsModule } from '@lib/core'; +// import { GlofasModule } from '@lib/glofas-adapter'; +import { TriggersModule } from './triggers/trigger.module'; + +@Module({ + imports: [ + ConfigModule.forRoot({ + isGlobal: true, + }), + PrismaModule.forRootWithConfig({ + isGlobal: true, + }), + HttpModule.register({ + global: true, + }), + + TriggersModule, + SettingsModule, + ], + controllers: [AppController], + providers: [AppService], +}) +export class AppModule {} diff --git a/apps/mock-api/src/app.service.ts b/apps/mock-api/src/app.service.ts new file mode 100644 index 0000000..de96258 --- /dev/null +++ b/apps/mock-api/src/app.service.ts @@ -0,0 +1,8 @@ +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class AppService { + getHello(): number { + return 10; + } +} diff --git a/apps/mock-api/src/common/index.ts b/apps/mock-api/src/common/index.ts new file mode 100644 index 0000000..b6beca7 --- /dev/null +++ b/apps/mock-api/src/common/index.ts @@ -0,0 +1,270 @@ +import * as cheerio from 'cheerio'; +export const getFormattedDate = (date: Date = new Date()) => { + // const date = new Date(); + // date.setDate(date.getDate() - 1); // Set date to previous day + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); // getMonth() returns 0-based month, hence add 1 + const day = String(date.getDate()).padStart(2, '0'); + + const dateTimeString = `${year}-${month}-${day}T00:00:00`; + const dateString = `${year}-${month}-${day}`; + + return { dateString, dateTimeString }; +}; +export function parseGlofasData(content: string) { + const $ = cheerio.load(content); + + // 2 yr return period table + const rpTable2yr = $( + 'table[class="table-forecast-result table-forecast-result-global"][summary="ECMWF-ENS > 2 yr RP"]', + ); + + // 5 yr return period table + const rpTable5yr = $( + 'table[class="table-forecast-result table-forecast-result-global"][summary="ECMWF-ENS > 5 yr RP"]', + ); + + // 20 yr return period table + const rpTable20yr = $( + 'table[class="table-forecast-result table-forecast-result-global"][summary="ECMWF-ENS > 20 yr RP"]', + ); + + // point forecast table + const pfTable = $('table.tbl_info_point[summary="Point Forecast"]'); + + const hydrographElement = $('.forecast_images').find( + 'img[alt="Discharge Hydrograph (ECMWF-ENS)"]', + ); + + if ( + rpTable2yr.length === 0 || + rpTable5yr.length === 0 || + rpTable20yr.length === 0 || + pfTable.length === 0 || + hydrographElement.length === 0 + ) { + return; + } + + const returnPeriodTable2yr = parseReturnPeriodTable(rpTable2yr, $); + const returnPeriodTable5yr = parseReturnPeriodTable(rpTable5yr, $); + const returnPeriodTable20yr = parseReturnPeriodTable(rpTable20yr, $); + const pointForecastData = parsePointForecast(pfTable, $); + const hydrographImageUrl = hydrographElement.attr('src'); + return { + returnPeriodTable2yr, + returnPeriodTable5yr, + returnPeriodTable20yr, + pointForecastData, + hydrographImageUrl, + }; +} +function parseReturnPeriodTable( + rpTable: cheerio.Cheerio, + $: cheerio.CheerioAPI, +) { + // first header row, consists of column names + const headerRow = rpTable.find('tr').first(); + // get column names (th elements in tr) + const returnPeriodHeaders = headerRow + .find('th') + .map((_, element) => $(element).text().trim()) + .toArray(); + + // first 10 data row (excluding the header) , data from latest day + const dataRow = rpTable.find('tr').slice(1, 11); + const returnPeriodData = []; + + for (const row of dataRow) { + const dataValues = $(row) + .find('td') + .map((_, element) => $(element).text().trim()) + .toArray(); + + returnPeriodData.push(dataValues); + } + + return { returnPeriodData, returnPeriodHeaders }; +} + +function parsePointForecast( + pfTable: cheerio.Cheerio, + $: cheerio.CheerioAPI, +) { + const headerRow = pfTable.find('tr').first(); + const columnNames = headerRow + .find('th') + .map((i, element) => $(element).text().trim()) + .toArray(); + + const dataRow = pfTable.find('tr').eq(1); + + const forecastDate = dataRow.find('td:nth-child(1)').text().trim(); // Using nth-child selector + const maxProbability = dataRow.find('td:nth-child(2)').text().trim(); + const alertLevel = dataRow.find('td:nth-child(3)').text().trim(); + const maxProbabilityStep = dataRow.find('td:nth-child(4)').text().trim(); + const dischargeTendencyImage = dataRow + .find('td:nth-child(5) img') + .attr('src'); // Extract image src + const peakForecasted = dataRow.find('td:nth-child(6)').text().trim(); + + return { + forecastDate: { + header: columnNames[0], + data: forecastDate, + }, + maxProbability: { + header: columnNames[1], + data: maxProbability, + }, + alertLevel: { + header: columnNames[2], + data: alertLevel, + }, + maxProbabilityStep: { + header: columnNames[3], + data: maxProbabilityStep, + }, + dischargeTendencyImage: { + header: columnNames[4], + data: dischargeTendencyImage, + }, + peakForecasted: { + header: columnNames[5], + data: peakForecasted, + }, + }; +} + +export const getTriggerAndActivityCompletionTimeDifference = ( + start: Date, + end: Date, +) => { + const trigger = new Date(start); + const completion = new Date(end); + + const isCompletedEarlier = completion < trigger; + + const msDifference = completion.getTime() - trigger.getTime(); + const absoluteMsDifference = Math.abs(msDifference); + + let differenceInSeconds = Math.floor(absoluteMsDifference / 1000); + + const days = Math.floor(differenceInSeconds / (24 * 3600)); + differenceInSeconds %= 24 * 3600; + + const hours = Math.floor(differenceInSeconds / 3600); + differenceInSeconds %= 3600; + + const minutes = Math.floor(differenceInSeconds / 60); + const seconds = differenceInSeconds % 60; + + const parts = [ + days ? `${days} day${days !== 1 ? 's' : ''}` : '', + hours ? `${hours} hour${hours !== 1 ? 's' : ''}` : '', + minutes ? `${minutes} minute${minutes !== 1 ? 's' : ''}` : '', + seconds ? `${seconds} second${seconds !== 1 ? 's' : ''}` : '', + ]; + + const result = parts.filter(Boolean).join(' '); + + return isCompletedEarlier ? `-${result}` : result; +}; + +export function buildQueryParams(seriesId: number, from = null, to = null) { + const currentDate = new Date().toISOString().split('T')[0]; + const endOfFrom = from ? new Date(from.setHours(23, 59, 59, 999)) : null; + + from = endOfFrom ? endOfFrom.toISOString().split('T')[0] : null; + to = to ? new Date(to).toISOString().split('T')[0] : null; + + return { + series_id: seriesId, + date_from: from || currentDate, + date_to: to || currentDate, + }; +} + +export function scrapeDataFromHtml(html: string): { [key: string]: any }[] { + if (!html?.trim()) return []; + + const results: { [key: string]: any }[] = []; + + // Pre-compiled regex patterns for better performance + const headerRegex = /]*>(.*?)<\/th>/gs; + const htmlTagRegex = /<[^>]*>/g; + const whitespaceRegex = /\s+/g; + + // Extract headers first + const headers: string[] = []; + let headerMatch: RegExpExecArray | null; + + while ((headerMatch = headerRegex.exec(html)) !== null) { + const headerText = headerMatch[1] + .replace(htmlTagRegex, '') + .replace(whitespaceRegex, ' ') + .trim(); + + if (headerText) { + headers.push(headerText); + } + } + + // If no headers found, return empty array + if (headers.length === 0) return []; + + // Create dynamic regex pattern based on number of headers + const cellPattern = ']*>(.*?)\\s*'; + const tableRowRegex = new RegExp( + `]*>\\s*${cellPattern.repeat(headers.length)}`, + 'gs', + ); + + let match: RegExpExecArray | null; + + while ((match = tableRowRegex.exec(html)) !== null) { + const rowData: { [key: string]: any } = {}; + let hasValidData = false; + + // Process each cell according to its header + for (let i = 0; i < headers.length; i++) { + const cellRaw = match[i + 1] + ?.replace(htmlTagRegex, '') + .replace(whitespaceRegex, ' ') + .trim(); + + if (!cellRaw) continue; + + const header = headers[i]; + const headerLower = header.toLowerCase(); + + // Handle different data types based on header name + if (headerLower.includes('date') || headerLower.includes('time')) { + // Handle date/time columns + const date = new Date(cellRaw); + if (!isNaN(date.getTime())) { + rowData[header] = date.toISOString(); + hasValidData = true; + } + } else { + // Try to parse as number first + const numericValue = parseFloat(cellRaw); + if (!isNaN(numericValue)) { + rowData[header] = numericValue; + hasValidData = true; + } else { + // Keep as string if not numeric + rowData[header] = cellRaw; + hasValidData = true; + } + } + } + + // Only add row if we have at least one valid data point + if (hasValidData && Object.keys(rowData).length > 0) { + results.push(rowData); + } + } + + return results; +} diff --git a/apps/mock-api/src/constants/datasourceUrls.ts b/apps/mock-api/src/constants/datasourceUrls.ts new file mode 100644 index 0000000..1670a64 --- /dev/null +++ b/apps/mock-api/src/constants/datasourceUrls.ts @@ -0,0 +1,18 @@ +export const hydrologyObservationUrl = + 'https://hydrology.gov.np/gss/api/observation'; + +export const riverStationUrl = + 'https://www.dhm.gov.np/frontend_dhm/site/getRiverWatchFilter'; + +export const rainfallStationUrl = + 'https://www.dhm.gov.np/frontend_dhm/hydrology/getRainfallFilter'; + +export const dhmRiverWatchUrl = + 'https://dhm.gov.np/site/getRiverWatchBySeriesId_Single'; + +export const dhmRainfallWatchUrl = + 'http://www.dhm.gov.np/frontend_dhm/hydrology/getRainfallWatchMapBySeriesId'; + +export const gfhUrl = 'https://floodforecasting.googleapis.com/v1'; + +export const glofasUrl = 'https://ows.globalfloods.eu/glofas-ows/ows.py'; diff --git a/apps/mock-api/src/data/dhm/index.ts b/apps/mock-api/src/data/dhm/index.ts new file mode 100644 index 0000000..02be378 --- /dev/null +++ b/apps/mock-api/src/data/dhm/index.ts @@ -0,0 +1,35 @@ +export const riverForecast = { + table: + '
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
DatePoint
\r\n
', + chart: + "", + filter: + '
Latest Water Level
    No data available in table
', +}; + +export const demoRiverForecast = [ + { datetime: '2025-10-17T00:00:00', value: 72.5 }, + { datetime: '2025-10-17T01:00:00', value: 73.1 }, + { datetime: '2025-10-17T02:00:00', value: 74.0 }, + { datetime: '2025-10-17T03:00:00', value: 75.2 }, + { datetime: '2025-10-17T04:00:00', value: 74.8 }, + { datetime: '2025-10-17T05:00:00', value: 73.5 }, + { datetime: '2025-10-17T06:00:00', value: 72.0 }, + { datetime: '2025-10-17T07:00:00', value: 71.5 }, + { datetime: '2025-10-17T08:00:00', value: 72.2 }, + { datetime: '2025-10-17T09:00:00', value: 73.0 }, + { datetime: '2025-10-17T10:00:00', value: 74.1 }, + { datetime: '2025-10-17T11:00:00', value: 75.0 }, + { datetime: '2025-10-17T12:00:00', value: 76.2 }, + { datetime: '2025-10-17T13:00:00', value: 77.0 }, + { datetime: '2025-10-17T14:00:00', value: 76.5 }, + { datetime: '2025-10-17T15:00:00', value: 75.3 }, + { datetime: '2025-10-17T16:00:00', value: 74.0 }, + { datetime: '2025-10-17T17:00:00', value: 73.2 }, + { datetime: '2025-10-17T18:00:00', value: 72.8 }, + { datetime: '2025-10-17T19:00:00', value: 72.0 }, + { datetime: '2025-10-17T20:00:00', value: 71.5 }, + { datetime: '2025-10-17T21:00:00', value: 71.8 }, + { datetime: '2025-10-17T22:00:00', value: 72.3 }, + { datetime: '2025-10-17T23:00:00', value: 72.7 }, +]; diff --git a/apps/mock-api/src/data/gfh/index.ts b/apps/mock-api/src/data/gfh/index.ts new file mode 100644 index 0000000..72c8767 --- /dev/null +++ b/apps/mock-api/src/data/gfh/index.ts @@ -0,0 +1,9591 @@ +import { GfhStationDetails } from '../../types/data-source'; + +export const gfhGauges = { + gauges: [ + { + location: { + latitude: 30.272916666665367, + longitude: 81.664583333329233, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120757190', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 30.177083333332064, + longitude: 81.447916666662479, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120760050', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 30.12291666666539, + longitude: 80.864583333329165, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120761360', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 30.085416666665367, + longitude: 81.527083333329131, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120762570', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 30.0354166666653, + longitude: 81.652083333329188, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120764470', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 30.010416666665375, + longitude: 81.760416666662536, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120765220', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.96041666666531, + longitude: 80.606249999995953, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120767020', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.96041666666531, + longitude: 80.677083333329108, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120767030', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.956249999998704, + longitude: 81.931249999995885, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120767160', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.952083333332041, + longitude: 80.677083333329108, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120767290', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.9437499999986, + longitude: 81.856249999995839, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120767540', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.872916666665279, + longitude: 81.164583333329176, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120769660', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.835416666665424, + longitude: 80.881249999995816, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120770900', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.827083333331984, + longitude: 81.260416666662479, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120771200', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.827083333331984, + longitude: 81.268749999995919, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120771210', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.793749999998624, + longitude: 81.743749999995885, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120772310', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.781249999998749, + longitude: 81.94374999999593, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120772630', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.760416666665265, + longitude: 82.085416666662525, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120773160', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.7562499999986, + longitude: 80.372916666662491, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120773280', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.752083333332, + longitude: 82.027083333329188, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120773400', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.74791666666539, + longitude: 80.372916666662491, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120773570', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.74791666666539, + longitude: 82.035416666662456, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120773580', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.74791666666539, + longitude: 82.06458333332921, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120773590', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.727083333332075, + longitude: 81.314583333329153, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120774400', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.706249999998761, + longitude: 80.3770833333291, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120775090', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.689583333332049, + longitude: 80.614583333329165, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120775760', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.6604166666653, + longitude: 81.885416666662593, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120776680', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.65208333333203, + longitude: 81.702083333329256, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120776890', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.64374999999859, + longitude: 80.506249999995816, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120777110', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.639583333331984, + longitude: 82.502083333329153, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120777280', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.622916666665279, + longitude: 81.856249999995839, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120777950', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.6104166666654, + longitude: 80.40624999999585, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120778310', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.6104166666654, + longitude: 81.777083333329244, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120778320', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.606249999998624, + longitude: 80.41458333332929, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120778440', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.606249999998624, + longitude: 81.7687499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120778450', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.593749999998749, + longitude: 80.8562499999959, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120778780', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.593749999998749, + longitude: 80.864583333329165, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120778790', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.593749999998749, + longitude: 82.297916666662445, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120778800', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.58541666666531, + longitude: 82.456249999995862, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120779110', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.581249999998647, + longitude: 81.227083333329119, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120779230', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.581249999998647, + longitude: 81.2354166666625, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120779240', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.556249999998727, + longitude: 81.2062499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120779870', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.556249999998727, + longitude: 82.560416666662434, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120779880', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.55208333333195, + longitude: 82.177083333329165, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120780030', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.547916666665287, + longitude: 82.714583333329074, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120780230', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.539583333332018, + longitude: 82.910416666662513, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120780630', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.539583333332018, + longitude: 82.9562499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120780640', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.535416666665409, + longitude: 81.793749999995725, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120780830', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.502083333332049, + longitude: 81.135416666662593, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120781650', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.493749999998613, + longitude: 83.056249999995714, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120781980', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.477083333331905, + longitude: 81.718749999995907, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120782430', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.477083333331905, + longitude: 83.147916666662582, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120782440', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.4729166666653, + longitude: 82.864583333329108, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120782570', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.45624999999859, + longitude: 80.272916666662525, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120783200', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.452083333331984, + longitude: 80.9062499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120783360', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.452083333331984, + longitude: 80.914583333329176, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120783370', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.452083333331984, + longitude: 81.460416666662525, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120783380', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.447916666665371, + longitude: 80.239583333329165, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120783510', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.447916666665371, + longitude: 80.2479166666626, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120783520', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.418749999998624, + longitude: 80.868749999995941, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120784250', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.410416666665355, + longitude: 80.868749999995941, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120784430', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.368749999998727, + longitude: 80.818749999995873, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120785420', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.364583333331893, + longitude: 80.789583333329119, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120785620', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.360416666665287, + longitude: 80.410416666662513, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120785730', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.360416666665287, + longitude: 80.818749999995873, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120785740', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.356249999998681, + longitude: 81.335416666662468, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120785840', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.352083333332018, + longitude: 80.40624999999585, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120786010', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.327083333332091, + longitude: 80.293749999995839, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120786950', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.327083333332094, + longitude: 80.456249999995919, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120786960', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.314583333332049, + longitude: 80.318749999995816, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120787460', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.314583333332049, + longitude: 81.7520833333291, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120787470', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.306249999998613, + longitude: 80.772916666662468, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120787780', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.27708333333203, + longitude: 82.206249999995919, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120788710', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.247916666665279, + longitude: 82.118749999995885, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120789770', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.227083333331962, + longitude: 82.002083333329267, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120790530', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.218749999998693, + longitude: 81.635416666662479, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120790750', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.218749999998693, + longitude: 81.9979166666626, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120790760', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.206249999998647, + longitude: 80.243749999995828, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120791140', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.202083333332041, + longitude: 81.914583333329176, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120791300', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.193749999998769, + longitude: 81.014583333329142, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120791670', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.193749999998769, + longitude: 81.022916666662582, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120791680', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.168749999998681, + longitude: 81.214583333329188, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120792560', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.160416666665409, + longitude: 81.21874999999585, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120792810', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.147916666665367, + longitude: 80.272916666662525, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120793260', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.139583333332091, + longitude: 81.5812499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120793610', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.135416666665265, + longitude: 80.339583333329131, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120793720', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.135416666665265, + longitude: 82.902083333329074, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120793750', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.127083333332049, + longitude: 81.56874999999593, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120794040', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.11458333333195, + longitude: 81.747916666662491, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120794370', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.106249999998735, + longitude: 81.09791666666257, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120794600', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.106249999998731, + longitude: 81.747916666662491, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120794610', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.102083333332075, + longitude: 81.102083333329233, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120794760', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.102083333332075, + longitude: 81.110416666662445, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120794770', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.077083333331984, + longitude: 83.947916666662536, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120795600', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.043749999998568, + longitude: 82.902083333329074, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120796750', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.022916666665253, + longitude: 81.143749999995862, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120797400', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.022916666665253, + longitude: 82.777083333329188, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120797420', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.022916666665253, + longitude: 83.910416666662513, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120797440', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.010416666665375, + longitude: 80.731249999995839, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120797790', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.010416666665375, + longitude: 80.743749999995885, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120797800', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.010416666665375, + longitude: 80.752083333329153, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120797810', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.993749999998727, + longitude: 82.577083333329142, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120798310', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.985416666665287, + longitude: 82.577083333329142, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120798570', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.977083333332018, + longitude: 82.62708333332921, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120798910', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.977083333332018, + longitude: 82.881249999995759, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120798920', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.972916666665409, + longitude: 82.868749999995885, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120799060', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.968749999998749, + longitude: 81.035416666662456, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120799150', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.968749999998749, + longitude: 82.881249999995759, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120799170', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.964583333331973, + longitude: 81.106249999995839, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120799260', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.943749999998658, + longitude: 80.985416666662559, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120800070', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.939583333332, + longitude: 80.977083333329119, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120800220', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.931249999998613, + longitude: 82.272916666662525, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120800430', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.931249999998613, + longitude: 82.281249999995737, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120800440', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.922916666665344, + longitude: 83.822916666662422, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120800670', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.914583333332075, + longitude: 81.477083333329233, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120800980', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.914583333332075, + longitude: 81.4854166666625, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120800990', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.90208333333203, + longitude: 83.060416666662547, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120801510', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.897916666665367, + longitude: 83.181249999995771, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120801630', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.885416666665321, + longitude: 83.7979166666625, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120802000', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.881249999998715, + longitude: 83.789583333329233, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120802100', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.864583333332007, + longitude: 83.335416666662411, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120802600', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.856249999998568, + longitude: 83.335416666662411, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120802860', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.847916666665355, + longitude: 80.41458333332929, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120803320', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.847916666665355, + longitude: 82.427083333329165, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120803330', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.843749999998693, + longitude: 80.422916666662559, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120803470', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.827083333332041, + longitude: 80.114583333329279, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120803910', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.818749999998769, + longitude: 81.739583333329222, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120804250', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.810416666665333, + longitude: 80.38124999999593, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120804430', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.806249999998727, + longitude: 81.689583333329153, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120804510', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.785416666665409, + longitude: 82.014583333329142, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120805200', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.785416666665409, + longitude: 82.302083333329051, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120805210', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.781249999998749, + longitude: 81.577083333329142, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120805360', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.764583333332094, + longitude: 81.664583333329233, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120806060', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.764583333332094, + longitude: 82.056249999995771, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120806070', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.764583333332094, + longitude: 82.06458333332921, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120806080', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.756249999998658, + longitude: 81.664583333329233, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120806420', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.74374999999856, + longitude: 81.260416666662479, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120806700', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.727083333332075, + longitude: 81.4187499999959, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120807350', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.702083333331927, + longitude: 80.6729166666625, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120807920', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.697916666665321, + longitude: 82.272916666662525, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120808110', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.681249999998613, + longitude: 82.210416666662582, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120808600', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.681249999998613, + longitude: 82.864583333329108, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120808610', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.6729166666654, + longitude: 82.206249999995919, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120809000', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.6729166666654, + longitude: 82.693749999995759, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120809010', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.668749999998735, + longitude: 82.014583333329142, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120809160', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.647916666665424, + longitude: 82.935416666662491, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120809900', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.643749999998647, + longitude: 80.639583333329142, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120809990', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.643749999998647, + longitude: 80.647916666662582, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120810000', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.643749999998647, + longitude: 82.039583333329233, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120810010', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.643749999998647, + longitude: 82.427083333329165, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120810020', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.635416666665371, + longitude: 82.039583333329233, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120810230', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.635416666665375, + longitude: 82.4229166666625, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120810240', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.635416666665375, + longitude: 82.62708333332921, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120810250', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.635416666665375, + longitude: 82.7520833333291, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120810260', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.627083333332109, + longitude: 82.62708333332921, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120810470', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.614583333332064, + longitude: 80.931249999995885, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120810930', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.614583333332064, + longitude: 82.172916666662559, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120810940', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.593749999998749, + longitude: 84.422916666662445, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120811570', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.589583333331973, + longitude: 81.035416666662456, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120811750', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.577083333332041, + longitude: 80.747916666662491, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120812060', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.568749999998658, + longitude: 84.731249999995725, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120812250', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.56041666666539, + longitude: 80.772916666662468, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120812540', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.56041666666539, + longitude: 80.781249999995907, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120812550', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.547916666665344, + longitude: 84.256249999995759, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120812890', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.547916666665344, + longitude: 84.7812499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120812900', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.543749999998681, + longitude: 83.364583333329165, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120813050', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.543749999998681, + longitude: 84.772916666662525, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120813070', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.539583333332075, + longitude: 83.356249999995725, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120813280', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.539583333332075, + longitude: 83.677083333329051, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120813290', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.52708333333203, + longitude: 83.656249999995737, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120813690', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.518749999998761, + longitude: 82.027083333329188, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120814000', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.514583333331927, + longitude: 81.652083333329188, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120814120', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.514583333331927, + longitude: 84.368749999995771, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120814140', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.510416666665321, + longitude: 81.693749999995816, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120814230', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.510416666665321, + longitude: 82.0312499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120814240', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.506249999998715, + longitude: 81.039583333329062, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120814300', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.4729166666653, + longitude: 84.956249999995748, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120815280', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.468749999998693, + longitude: 82.006249999995873, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120815350', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.460416666665424, + longitude: 82.002083333329267, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120815480', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.452083333331984, + longitude: 81.006249999995873, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120815690', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.447916666665375, + longitude: 84.902083333329074, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120815830', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.443749999998769, + longitude: 80.968749999995907, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120815970', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.439583333332109, + longitude: 81.8437499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120816090', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.435416666665333, + longitude: 81.835416666662525, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120816260', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.435416666665333, + longitude: 84.397916666662525, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120816270', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.435416666665333, + longitude: 84.897916666662411, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120816280', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.43124999999867, + longitude: 81.035416666662456, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120816490', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.42291666666523, + longitude: 81.039583333329062, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120816760', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.406249999998749, + longitude: 81.202083333329142, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120817220', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.40208333333192, + longitude: 82.50624999999593, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120817440', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.393749999998704, + longitude: 81.318749999995759, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120817710', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.393749999998704, + longitude: 82.502083333329153, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120817720', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.389583333332041, + longitude: 81.310416666662547, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120817810', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.377083333332, + longitude: 83.572916666662479, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120818130', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.37291666666539, + longitude: 82.810416666662434, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120818340', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.347916666665409, + longitude: 83.568749999995873, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120819000', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.343749999998639, + longitude: 82.597916666662456, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120819210', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.339583333331973, + longitude: 82.6062499999959, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120819360', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.339583333331973, + longitude: 85.443749999995759, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120819380', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.335416666665367, + longitude: 83.164583333329119, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120819470', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.327083333332094, + longitude: 83.160416666662456, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120819760', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.327083333332094, + longitude: 84.397916666662525, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120819770', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.322916666665321, + longitude: 84.4062499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120819930', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.297916666665344, + longitude: 83.931249999995828, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120820640', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.297916666665344, + longitude: 83.9395833333291, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120820650', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.2854166666653, + longitude: 82.585416666662582, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120821140', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.2854166666653, + longitude: 84.3604166666625, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120821150', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.281249999998693, + longitude: 82.577083333329142, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120821260', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.281249999998693, + longitude: 85.372916666662547, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120821280', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.281249999998693, + longitude: 85.381249999995816, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120821290', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.268749999998647, + longitude: 81.914583333329176, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120821580', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.264583333331984, + longitude: 83.6104166666625, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120821770', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.260416666665371, + longitude: 81.91041666666257, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120821950', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.23541666666523, + longitude: 84.8770833333291, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120822870', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.206249999998704, + longitude: 83.672916666662445, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120823790', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.202083333332041, + longitude: 84.193749999995816, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120823860', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.1937499999986, + longitude: 85.0770833333292, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120824170', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.189583333332, + longitude: 82.681249999995885, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120824240', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.189583333332, + longitude: 83.272916666662468, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120824260', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.189583333332, + longitude: 83.281249999995907, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120824270', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.18541666666539, + longitude: 85.3437499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120824370', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.181249999998727, + longitude: 83.989583333329165, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120824520', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.172916666665287, + longitude: 83.989583333329165, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120824790', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.172916666665287, + longitude: 84.439583333329153, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120824800', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.168749999998681, + longitude: 84.447916666662422, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120824940', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.168749999998681, + longitude: 85.3437499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120824950', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.160416666665409, + longitude: 85.347916666662456, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120825270', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.156249999998639, + longitude: 84.2229166666624, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120825410', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.152083333331973, + longitude: 82.906249999995907, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120825520', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.147916666665367, + longitude: 82.914583333329176, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120825660', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.127083333332049, + longitude: 83.318749999995759, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120826330', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.118749999998784, + longitude: 83.231249999995839, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120826510', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.118749999998784, + longitude: 83.3145833333291, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120826520', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.114583333332007, + longitude: 86.177083333329108, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120826640', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.110416666665344, + longitude: 83.231249999995839, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120826750', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.08958333333203, + longitude: 81.522916666662468, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120827190', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.08124999999859, + longitude: 81.527083333329131, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120827490', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.08124999999859, + longitude: 81.735416666662445, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120827500', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.077083333331984, + longitude: 85.214583333329131, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120827620', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.072916666665375, + longitude: 82.210416666662582, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120827720', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.072916666665375, + longitude: 83.347916666662513, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120827730', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.064583333332109, + longitude: 82.214583333329188, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120828070', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.060416666665279, + longitude: 84.477083333329176, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120828200', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.05624999999867, + longitude: 81.72291666666257, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120828350', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.0479166666654, + longitude: 81.72291666666257, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120828510', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.043749999998795, + longitude: 82.789583333329119, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120828640', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.035416666665355, + longitude: 82.314583333329153, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120828950', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.031249999998749, + longitude: 82.277083333329131, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120829100', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.027083333332087, + longitude: 84.0770833333292, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120829190', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.018749999998647, + longitude: 84.0812499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120829440', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.014583333332041, + longitude: 83.602083333329233, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120829520', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.014583333332041, + longitude: 83.6104166666625, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120829530', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.993749999998727, + longitude: 82.9562499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120830140', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.989583333332121, + longitude: 85.9729166666624, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120830210', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.985416666665451, + longitude: 83.585416666662354, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120830350', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.981249999998681, + longitude: 84.777083333329188, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120830510', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.977083333332018, + longitude: 85.181249999995771, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120830670', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.977083333332018, + longitude: 85.18958333332921, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120830680', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.977083333332018, + longitude: 85.6395833333292, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120830700', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.977083333332018, + longitude: 86.202083333329028, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120830710', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.977083333332018, + longitude: 86.210416666662468, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120830720', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.972916666665409, + longitude: 83.468749999995907, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120830780', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.972916666665409, + longitude: 83.477083333329176, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120830790', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.972916666665409, + longitude: 84.2645833333292, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120830800', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.964583333331973, + longitude: 84.2645833333292, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120830960', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.960416666665367, + longitude: 84.422916666662445, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120831080', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.952083333332094, + longitude: 84.418749999995839, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120831300', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.943749999998658, + longitude: 83.28541666666257, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120831510', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.939583333332049, + longitude: 83.443749999995816, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120831610', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.93541666666539, + longitude: 82.9395833333291, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120831720', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.931249999998784, + longitude: 82.947916666662536, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120831820', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.9104166666653, + longitude: 82.922916666662388, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120832240', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.906249999998693, + longitude: 85.231249999995839, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120832310', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.90208333333203, + longitude: 82.922916666662388, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120832370', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.90208333333203, + longitude: 84.535416666662456, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120832380', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.90208333333203, + longitude: 84.5437499999959, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120832390', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.897916666665424, + longitude: 85.231249999995839, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120832500', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.89374999999859, + longitude: 83.872916666662491, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120832620', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.885416666665375, + longitude: 82.810416666662434, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120832770', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.885416666665375, + longitude: 83.872916666662491, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120832780', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.885416666665371, + longitude: 86.227083333329176, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120832790', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.881249999998715, + longitude: 82.802083333329165, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120832900', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.877083333332109, + longitude: 83.9395833333291, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120833090', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.86874999999867, + longitude: 83.9395833333291, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120833360', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.86874999999867, + longitude: 87.422916666662388, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120833370', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.864583333332064, + longitude: 85.110416666662388, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120833490', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.856249999998795, + longitude: 84.556249999995771, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120833710', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.856249999998795, + longitude: 84.56458333332921, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120833720', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.856249999998795, + longitude: 85.114583333329165, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120833730', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.847916666665355, + longitude: 87.431249999995828, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120833930', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.843749999998749, + longitude: 82.497916666662491, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120834130', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.839583333332087, + longitude: 85.581249999995691, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120834320', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.83541666666531, + longitude: 85.572916666662479, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120834420', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.831249999998647, + longitude: 82.747916666662491, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120834540', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.822916666665435, + longitude: 82.747916666662491, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120834820', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.822916666665435, + longitude: 84.464583333329074, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120834830', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.818749999998769, + longitude: 84.777083333329188, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120834960', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.814583333332, + longitude: 84.7854166666624, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120835120', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.814583333332, + longitude: 85.014583333329085, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120835140', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.810416666665333, + longitude: 84.835416666662468, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120835260', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.806249999998727, + longitude: 85.006249999995816, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120835410', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.797916666665454, + longitude: 85.006249999995816, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120835730', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.789583333332018, + longitude: 86.727083333329062, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120836050', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.772916666665367, + longitude: 87.452083333329142, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120836670', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.764583333332094, + longitude: 86.197916666662422, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120836970', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.764583333332094, + longitude: 87.452083333329142, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120836980', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.752083333332049, + longitude: 85.056249999995885, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120837540', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.74791666666539, + longitude: 83.460416666662468, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120837690', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.74791666666539, + longitude: 83.468749999995907, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120837700', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.743749999998784, + longitude: 84.427083333329108, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120837900', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.73958333333195, + longitude: 86.168749999995839, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120838030', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.735416666665344, + longitude: 85.7854166666624, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120838220', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.718749999998639, + longitude: 87.302083333329165, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120838660', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.71458333333203, + longitude: 85.672916666662388, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120838820', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.710416666665424, + longitude: 85.664583333329119, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120839010', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.697916666665321, + longitude: 87.368749999995714, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120839480', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.693749999998715, + longitude: 85.306249999995828, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120839630', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.693749999998715, + longitude: 87.360416666662445, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120839640', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.6729166666654, + longitude: 83.118749999995828, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120840380', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.6729166666654, + longitude: 86.460416666662411, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120840390', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.664583333331962, + longitude: 87.797916666662445, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120840590', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.639583333332041, + longitude: 85.710416666662411, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120841230', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.618749999998727, + longitude: 86.077083333329142, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120841840', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.610416666665454, + longitude: 87.360416666662445, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120841980', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.606249999998681, + longitude: 82.96874999999585, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120842100', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.602083333332018, + longitude: 87.360416666662445, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120842250', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.589583333331973, + longitude: 84.493749999995828, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120842480', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.589583333331973, + longitude: 85.722916666662456, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120842490', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.585416666665367, + longitude: 84.485416666662388, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120842590', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.577083333332091, + longitude: 84.489583333329222, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120842810', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.577083333332094, + longitude: 87.2979166666625, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120842830', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.572916666665265, + longitude: 84.160416666662456, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120842970', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.564583333332049, + longitude: 84.160416666662456, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120843250', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.564583333332049, + longitude: 87.2520833333291, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120843260', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.56041666666539, + longitude: 82.993749999995771, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120843510', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.56041666666539, + longitude: 84.122916666662434, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120843520', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.56041666666539, + longitude: 87.260416666662366, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120843540', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.556249999998784, + longitude: 84.181249999995771, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120843690', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.556249999998784, + longitude: 84.7062499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120843700', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.55208333333195, + longitude: 82.997916666662434, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120843770', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.55208333333195, + longitude: 83.922916666662559, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120843780', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.55208333333195, + longitude: 83.972916666662456, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120843790', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.55208333333195, + longitude: 84.122916666662434, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120843800', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.547916666665344, + longitude: 83.931249999995828, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120843920', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.547916666665344, + longitude: 84.010416666662479, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120843930', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.547916666665344, + longitude: 85.231249999995839, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120843940', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.547916666665344, + longitude: 85.239583333329051, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120843950', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.543749999998735, + longitude: 87.235416666662388, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120844020', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.539583333332075, + longitude: 84.014583333329085, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120844090', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.531249999998639, + longitude: 87.802083333329051, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120844210', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.518749999998761, + longitude: 84.802083333329108, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120844560', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.510416666665321, + longitude: 85.793749999995839, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120844800', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.506249999998715, + longitude: 85.802083333329108, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120844950', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.4854166666654, + longitude: 87.614583333329051, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120845490', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.481249999998795, + longitude: 86.114583333329165, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120845630', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.481249999998795, + longitude: 86.714583333329188, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120845640', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.477083333332128, + longitude: 85.247916666662491, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120845740', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.477083333332128, + longitude: 86.722916666662456, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120845760', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.477083333332128, + longitude: 87.085416666662411, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120845770', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.472916666665355, + longitude: 85.256249999995759, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120845980', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.460416666665253, + longitude: 85.039583333329176, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120846350', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.460416666665253, + longitude: 86.727083333329062, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120846360', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.456249999998647, + longitude: 85.81041666666232, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120846530', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.456249999998647, + longitude: 86.7354166666625, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120846540', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.452083333332041, + longitude: 87.143749999995691, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120846650', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.447916666665375, + longitude: 85.814583333329153, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120846740', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.431249999998727, + longitude: 83.231249999995839, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120847340', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.427083333332064, + longitude: 85.014583333329085, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120847470', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.422916666665454, + longitude: 87.12708333332904, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120847640', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.418749999998624, + longitude: 85.014583333329085, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120847770', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.377083333332, + longitude: 85.477083333329119, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120848980', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.377083333332, + longitude: 86.035416666662513, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120848990', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.377083333332, + longitude: 87.6312499999957, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120849000', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.37291666666539, + longitude: 87.622916666662491, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120849150', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.364583333332121, + longitude: 86.681249999995828, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120849540', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.364583333332121, + longitude: 87.860416666662388, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120849550', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.356249999998681, + longitude: 85.977083333329062, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120849830', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.352083333332075, + longitude: 85.985416666662445, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120850030', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.347916666665469, + longitude: 85.631249999995759, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120850140', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.331249999998761, + longitude: 85.422916666662445, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120850660', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.327083333331984, + longitude: 85.414583333329176, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120850840', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.327083333331984, + longitude: 86.768749999995862, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120850850', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.30624999999867, + longitude: 87.197916666662422, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120851690', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.302083333332007, + longitude: 87.206249999995634, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120851830', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.293749999998731, + longitude: 87.693749999995646, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120852050', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.289583333332128, + longitude: 87.202083333329028, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120852170', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.289583333332128, + longitude: 87.835416666662411, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120852190', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.285416666665355, + longitude: 87.210416666662468, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120852370', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.281249999998693, + longitude: 87.764583333329028, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120852470', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.277083333332087, + longitude: 86.668749999995725, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120852620', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.272916666665253, + longitude: 86.677083333329165, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120852770', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.268749999998647, + longitude: 87.327083333329085, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120852900', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.264583333332041, + longitude: 86.65624999999585, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120853040', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.264583333332041, + longitude: 87.197916666662422, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120853050', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.264583333332041, + longitude: 87.206249999995634, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120853060', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.252083333331939, + longitude: 86.202083333329028, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120853530', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.222916666665409, + longitude: 85.493749999995828, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120854470', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.218749999998749, + longitude: 85.5020833333291, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120854630', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.218749999998749, + longitude: 87.235416666662388, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120854640', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.218749999998749, + longitude: 87.243749999995828, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120854650', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.197916666665435, + longitude: 86.381249999995816, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120855340', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.193749999998658, + longitude: 86.372916666662377, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120855490', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.172916666665344, + longitude: 85.497916666662434, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120856110', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.164583333332075, + longitude: 84.847916666662343, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120856360', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.164583333332075, + longitude: 87.772916666662468, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120856370', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.160416666665469, + longitude: 87.710416666662354, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120856480', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.147916666665367, + longitude: 86.431249999995657, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120856930', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.143749999998761, + longitude: 87.693749999995646, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120857040', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.131249999998715, + longitude: 87.647916666662411, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120857360', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.114583333332007, + longitude: 87.606249999995782, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120857840', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.114583333332007, + longitude: 87.614583333329051, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120857850', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.093749999998693, + longitude: 86.697916666662479, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120858410', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.089583333332087, + longitude: 86.006249999995759, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120858520', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.064583333332109, + longitude: 87.564583333329153, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120859370', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.052083333332064, + longitude: 87.181249999995714, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120859630', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.043749999998795, + longitude: 84.964583333329188, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120859960', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.035416666665355, + longitude: 87.5354166666624, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120860300', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.014583333332041, + longitude: 86.197916666662422, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120861040', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.014583333332041, + longitude: 86.747916666662377, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120861050', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.006249999998658, + longitude: 86.747916666662377, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120861240', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.989583333332121, + longitude: 84.810416666662547, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120861660', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.985416666665344, + longitude: 87.497916666662434, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120861730', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.981249999998681, + longitude: 86.756249999995816, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120861870', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.960416666665367, + longitude: 86.364583333329108, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120862650', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.947916666665321, + longitude: 86.277083333329074, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120863120', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.947916666665321, + longitude: 86.285416666662456, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120863130', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.947916666665321, + longitude: 86.427083333329051, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120863140', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.939583333332049, + longitude: 86.427083333329051, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120863440', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.927083333332007, + longitude: 87.114583333329165, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120863880', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.9229166666654, + longitude: 87.1562499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120863950', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.918749999998735, + longitude: 87.1104166666625, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120864040', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.914583333332128, + longitude: 87.1562499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120864110', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.902083333332087, + longitude: 85.372916666662547, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120864610', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.897916666665424, + longitude: 86.9062499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120864730', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.893749999998647, + longitude: 85.37708333332921, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120864910', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.893749999998647, + longitude: 87.952083333329028, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120864920', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.86874999999867, + longitude: 85.352083333329062, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120865510', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.86874999999867, + longitude: 85.764583333329085, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120865520', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.860416666665454, + longitude: 87.9062499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120865670', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.860416666665454, + longitude: 87.914583333329062, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120865680', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.831249999998704, + longitude: 85.256249999995759, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120866410', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.831249999998704, + longitude: 85.2645833333292, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120866420', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.827083333332041, + longitude: 87.781249999995737, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120866510', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.756249999998658, + longitude: 85.839583333329074, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120868640', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.743749999998784, + longitude: 86.527083333329188, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120868980', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.718749999998693, + longitude: 86.193749999995816, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120869820', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.718749999998693, + longitude: 86.202083333329028, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120869830', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.710416666665424, + longitude: 86.993749999995714, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120870040', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.685416666665333, + longitude: 87.152083333329131, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120870760', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.677083333332064, + longitude: 87.152083333329131, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120870950', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.664583333332018, + longitude: 87.952083333329028, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120871200', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.664583333332018, + longitude: 87.960416666662468, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120871210', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.635416666665435, + longitude: 87.306249999995771, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120871960', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.6312499999986, + longitude: 87.2979166666625, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120872110', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.618749999998727, + longitude: 88.139583333329085, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120872530', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.614583333332121, + longitude: 88.131249999995816, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120872600', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.589583333331973, + longitude: 87.6437499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120873530', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.581249999998761, + longitude: 85.8770833333291, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120873810', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.568749999998658, + longitude: 86.964583333329131, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120874290', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.568749999998658, + longitude: 86.9729166666624, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120874300', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.560416666665446, + longitude: 88.114583333329108, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120874600', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.560416666665446, + longitude: 88.122916666662377, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120874610', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.531249999998693, + longitude: 86.931249999995771, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120875600', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.49374999999867, + longitude: 88.0937499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120876700', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.477083333331962, + longitude: 87.481249999995725, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120877220', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.447916666665435, + longitude: 87.335416666662354, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120878060', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.447916666665435, + longitude: 87.839583333329074, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120878080', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.443749999998769, + longitude: 87.327083333329085, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120878280', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.414583333332018, + longitude: 87.935416666662377, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120879200', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.410416666665409, + longitude: 87.752083333329153, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4120879350', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 30.110416666665344, + longitude: 82.0479166666625, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121436190', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 30.052083333332007, + longitude: 80.772916666662468, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121436820', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 30.010416666665371, + longitude: 80.747916666662491, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121437340', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 30.002083333331939, + longitude: 81.993749999995828, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121437440', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.893749999998761, + longitude: 80.572916666662536, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121438880', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.889583333332094, + longitude: 81.310416666662547, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121438950', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.8479166666653, + longitude: 80.539583333329176, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121439490', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.843749999998693, + longitude: 82.2187499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121439580', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.835416666665424, + longitude: 82.1437499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121439700', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.80624999999867, + longitude: 81.864583333329108, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121440050', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.79791666666523, + longitude: 80.839583333329188, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121440130', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.793749999998624, + longitude: 80.489583333329108, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121440180', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.781249999998749, + longitude: 81.431249999995771, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121440420', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.752083333332, + longitude: 80.802083333329222, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121440740', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.727083333332075, + longitude: 80.731249999995839, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121441090', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.685416666665219, + longitude: 82.5187499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121441580', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.65208333333203, + longitude: 80.977083333329119, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121441920', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.639583333331984, + longitude: 81.306249999995885, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121442110', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.593749999998749, + longitude: 82.027083333329188, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121442560', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.535416666665409, + longitude: 82.66041666666257, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121443210', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.531249999998639, + longitude: 80.356249999995782, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121443240', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.506249999998658, + longitude: 80.5770833333292, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121443500', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.481249999998735, + longitude: 81.022916666662582, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121443750', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.46458333333203, + longitude: 82.7937499999959, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121444050', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.443749999998715, + longitude: 80.493749999995941, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121444340', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.4229166666654, + longitude: 82.052083333329108, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121444620', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.410416666665355, + longitude: 81.718749999995907, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121444830', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.385416666665435, + longitude: 81.981249999995725, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121445090', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.314583333332049, + longitude: 81.985416666662559, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121446040', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.31041666666539, + longitude: 81.293749999995839, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121446100', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.297916666665344, + longitude: 82.339583333329244, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121446220', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.297916666665344, + longitude: 82.352083333329119, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121446230', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.289583333332075, + longitude: 80.8562499999959, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121446300', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.289583333332075, + longitude: 81.25208333332921, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121446310', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.252083333331939, + longitude: 80.947916666662593, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121446820', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.24374999999867, + longitude: 80.9062499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121446870', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.2354166666654, + longitude: 81.214583333329188, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121446960', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.222916666665355, + longitude: 82.3312499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121447140', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.206249999998647, + longitude: 82.66041666666257, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121447370', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.197916666665371, + longitude: 80.289583333329233, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121447490', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.172916666665287, + longitude: 81.385416666662536, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121447860', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.143749999998704, + longitude: 82.647916666662525, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121448210', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.131249999998658, + longitude: 80.4854166666625, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121448380', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.118749999998613, + longitude: 82.614583333329165, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121448530', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.110416666665344, + longitude: 80.156249999995907, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121448680', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.102083333332075, + longitude: 81.8604166666625, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121448810', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.085416666665424, + longitude: 80.6562499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121449040', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.077083333331984, + longitude: 81.4687499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121449160', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.072916666665321, + longitude: 82.489583333329108, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121449240', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.064583333331878, + longitude: 82.5187499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121449400', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 29.022916666665253, + longitude: 81.422916666662559, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121449890', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.989583333332064, + longitude: 80.106249999995839, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121450230', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.985416666665287, + longitude: 83.347916666662513, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121450260', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.972916666665409, + longitude: 80.847916666662456, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121450450', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.972916666665409, + longitude: 82.2354166666625, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121450460', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.93541666666539, + longitude: 82.9562499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121450890', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.922916666665344, + longitude: 80.25208333332921, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121451050', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.9104166666653, + longitude: 81.652083333329188, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121451170', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.9104166666653, + longitude: 81.81458333332921, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121451180', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.906249999998639, + longitude: 81.260416666662479, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121451240', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.906249999998639, + longitude: 81.4354166666626, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121451250', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.90208333333203, + longitude: 82.510416666662593, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121451300', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.885416666665321, + longitude: 81.947916666662536, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121451510', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.877083333332049, + longitude: 81.052083333329165, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121451600', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.872916666665446, + longitude: 81.135416666662593, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121451710', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.8604166666654, + longitude: 80.235416666662559, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121451870', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.8604166666654, + longitude: 83.28541666666257, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121451880', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.831249999998647, + longitude: 81.2312499999959, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121452210', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.822916666665375, + longitude: 82.160416666662513, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121452290', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.810416666665333, + longitude: 83.764583333329142, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121452480', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.793749999998624, + longitude: 80.539583333329176, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121452750', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.77291666666531, + longitude: 81.343749999995907, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121453000', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.77291666666531, + longitude: 83.714583333329244, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121453010', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.752083333332, + longitude: 83.693749999995759, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121453280', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.727083333332075, + longitude: 80.9062499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121453490', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.722916666665238, + longitude: 80.40624999999585, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121453570', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.710416666665367, + longitude: 83.00208333332921, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121453710', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.706249999998761, + longitude: 80.543749999995839, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121453790', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.706249999998761, + longitude: 83.643749999995862, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121453800', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.6604166666653, + longitude: 82.5187499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121454410', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.647916666665424, + longitude: 84.068749999995759, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121454610', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.635416666665371, + longitude: 80.418749999995953, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121454800', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.635416666665375, + longitude: 83.093749999995907, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121454810', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.631249999998769, + longitude: 83.618749999995771, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121454850', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.61874999999867, + longitude: 84.143749999995748, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121455010', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.614583333332064, + longitude: 81.493749999995885, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121455030', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.589583333331973, + longitude: 84.643749999995862, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121455380', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.577083333332041, + longitude: 81.9979166666626, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121455580', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.572916666665435, + longitude: 81.547916666662445, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121455650', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.568749999998658, + longitude: 82.914583333329176, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121455720', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.56041666666539, + longitude: 81.256249999995816, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121455820', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.522916666665367, + longitude: 80.827083333329142, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121456310', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.522916666665367, + longitude: 83.510416666662536, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121456320', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.493749999998613, + longitude: 84.014583333329085, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121456750', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.493749999998613, + longitude: 85.060416666662491, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121456760', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.489583333332007, + longitude: 83.072916666662422, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121456800', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.477083333331962, + longitude: 82.527083333329244, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121456940', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.4729166666653, + longitude: 83.872916666662491, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121457010', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.468749999998693, + longitude: 83.631249999995816, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121457080', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.464583333332087, + longitude: 83.381249999995873, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121457120', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.439583333332109, + longitude: 81.464583333329188, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121457470', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.418749999998624, + longitude: 82.264583333329256, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121457770', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.418749999998624, + longitude: 84.118749999995828, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121457780', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.414583333332018, + longitude: 81.577083333329142, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121457860', + qualityVerified: true, + hasModel: true, + }, + { + location: { + latitude: 28.406249999998749, + longitude: 83.397916666662525, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121458010', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.39791666666531, + longitude: 83.9812499999959, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121458140', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.389583333332041, + longitude: 82.189583333329267, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121458260', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.385416666665435, + longitude: 83.822916666662422, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121458290', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.356249999998681, + longitude: 81.718749999995907, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121458700', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.339583333331973, + longitude: 84.902083333329074, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121458930', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.331249999998761, + longitude: 84.093749999995737, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121459040', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.310416666665446, + longitude: 82.243749999995771, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121459340', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.306249999998784, + longitude: 82.018749999995919, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121459370', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.293749999998735, + longitude: 84.90624999999585, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121459550', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.289583333331962, + longitude: 82.247916666662547, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121459630', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.289583333331962, + longitude: 83.756249999995873, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121459640', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.27708333333203, + longitude: 82.102083333329176, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121459790', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.27708333333203, + longitude: 82.7520833333291, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121459800', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.272916666665424, + longitude: 81.360416666662616, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121459860', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.272916666665424, + longitude: 84.53124999999585, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121459870', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.272916666665424, + longitude: 85.260416666662366, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121459880', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.252083333332109, + longitude: 81.372916666662491, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121460180', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.252083333332109, + longitude: 82.731249999995782, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121460190', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.227083333332018, + longitude: 81.577083333329142, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121460470', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.222916666665355, + longitude: 83.4229166666625, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121460540', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.21041666666531, + longitude: 85.668749999995782, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121460650', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.197916666665435, + longitude: 82.985416666662559, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121460780', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.197916666665435, + longitude: 85.585416666662525, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121460790', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.1937499999986, + longitude: 85.4520833333292, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121460850', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.189583333332, + longitude: 84.71874999999585, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121460890', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.18541666666539, + longitude: 81.531249999995907, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121460930', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.181249999998727, + longitude: 81.322916666662593, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121461010', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.181249999998727, + longitude: 82.0312499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121461020', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.172916666665287, + longitude: 84.614583333329108, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121461130', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.164583333332075, + longitude: 82.093749999995737, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121461250', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.152083333331973, + longitude: 83.635416666662422, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121461430', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.147916666665367, + longitude: 84.864583333329222, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121461490', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.122916666665446, + longitude: 82.114583333329051, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121461870', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.122916666665446, + longitude: 84.085416666662468, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121461880', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.102083333331905, + longitude: 83.872916666662491, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121462080', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.08958333333203, + longitude: 85.006249999995816, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121462230', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.08124999999859, + longitude: 83.581249999995748, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121462310', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.08124999999859, + longitude: 84.660416666662343, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121462320', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.068749999998715, + longitude: 81.827083333329142, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121462510', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.068749999998715, + longitude: 85.75208333332921, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121462520', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.064583333332109, + longitude: 82.647916666662525, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121462550', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.064583333332109, + longitude: 84.064583333329153, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121462560', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.052083333332064, + longitude: 81.868749999995771, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121462780', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.052083333332064, + longitude: 84.231249999995839, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121462790', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.052083333332064, + longitude: 84.818749999995816, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121462800', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.0479166666654, + longitude: 81.918749999995782, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121462860', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.031249999998749, + longitude: 81.96874999999585, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121463100', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.031249999998749, + longitude: 83.777083333329188, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121463110', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.031249999998749, + longitude: 84.964583333329188, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121463120', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 28.010416666665435, + longitude: 82.072916666662422, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121463330', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.997916666665333, + longitude: 82.431249999995771, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121463540', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.997916666665333, + longitude: 85.789583333329, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121463550', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.989583333332121, + longitude: 84.56458333332921, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121463710', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.972916666665409, + longitude: 85.535416666662456, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121463910', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.964583333331973, + longitude: 82.202083333329142, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121464030', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.952083333332094, + longitude: 85.789583333329, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121464160', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.939583333332049, + longitude: 81.772916666662411, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121464330', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.939583333332049, + longitude: 85.93958333332904, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121464340', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.927083333332007, + longitude: 82.239583333329108, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121464500', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.927083333332007, + longitude: 83.310416666662491, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121464510', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.922916666665344, + longitude: 85.385416666662422, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121464600', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.9104166666653, + longitude: 83.631249999995816, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121464760', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.90208333333203, + longitude: 83.739583333329165, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121464910', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.885416666665375, + longitude: 84.3312499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121465040', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.885416666665375, + longitude: 85.910416666662456, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121465050', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.881249999998715, + longitude: 82.352083333329119, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121465190', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.881249999998715, + longitude: 86.427083333329051, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121465200', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.8604166666654, + longitude: 82.435416666662377, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121465510', + qualityVerified: true, + hasModel: true, + }, + { + location: { + latitude: 27.856249999998795, + longitude: 84.102083333329119, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121465590', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.847916666665355, + longitude: 85.768749999995691, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121465680', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.843749999998749, + longitude: 84.164583333329062, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121465760', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.83541666666531, + longitude: 82.539583333329119, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121465840', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.827083333332041, + longitude: 82.62708333332921, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121465900', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.827083333332041, + longitude: 84.297916666662388, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121465910', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.810416666665333, + longitude: 84.697916666662536, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121466070', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.806249999998727, + longitude: 84.90624999999585, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121466100', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.802083333332121, + longitude: 85.8937499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121466140', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.793749999998681, + longitude: 83.547916666662559, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121466250', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.764583333332094, + longitude: 85.8812499999957, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121466600', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.727083333332075, + longitude: 83.927083333329222, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121467040', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.722916666665469, + longitude: 87.968749999995737, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121467110', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.677083333332007, + longitude: 86.102083333329119, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121467620', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.6729166666654, + longitude: 85.3437499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121467640', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.6729166666654, + longitude: 86.714583333329188, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121467650', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.668749999998795, + longitude: 84.260416666662422, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121467700', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.668749999998795, + longitude: 85.3604166666625, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121467710', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.656249999998693, + longitude: 86.814583333329153, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121467890', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.652083333332087, + longitude: 83.864583333329051, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121467980', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.652083333332087, + longitude: 87.918749999995839, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121467990', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.643749999998647, + longitude: 86.310416666662434, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121468110', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.631249999998769, + longitude: 86.697916666662479, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121468270', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.618749999998727, + longitude: 83.335416666662411, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121468390', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.589583333331973, + longitude: 85.852083333329176, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121468670', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.589583333331973, + longitude: 88.022916666662411, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121468680', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.585416666665367, + longitude: 84.918749999995725, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121468730', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.585416666665367, + longitude: 85.518749999995748, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121468740', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.585416666665367, + longitude: 86.410416666662343, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121468750', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.581249999998704, + longitude: 86.214583333329131, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121468800', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.581249999998704, + longitude: 86.902083333329188, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121468810', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.572916666665265, + longitude: 84.881249999995759, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121468950', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.568749999998658, + longitude: 86.677083333329165, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121469000', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.564583333332049, + longitude: 84.352083333329119, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121469060', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.564583333332049, + longitude: 87.639583333329142, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121469070', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.556249999998784, + longitude: 84.572916666662479, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121469180', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.547916666665344, + longitude: 86.581249999995862, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121469360', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.543749999998735, + longitude: 82.822916666662479, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121469420', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.535416666665469, + longitude: 83.614583333329108, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121469490', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.531249999998639, + longitude: 83.414583333329233, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121469550', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.52708333333203, + longitude: 86.356249999995839, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121469600', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.518749999998761, + longitude: 83.347916666662513, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121469690', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.514583333331984, + longitude: 85.602083333329, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121469720', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.506249999998715, + longitude: 86.839583333329074, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121469910', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.502083333332109, + longitude: 85.714583333329188, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121469970', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.497916666665446, + longitude: 86.577083333329085, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121470010', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.489583333332007, + longitude: 84.289583333329176, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121470120', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.477083333332128, + longitude: 86.293749999995725, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121470250', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.460416666665253, + longitude: 87.7229166666624, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121470430', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.452083333332041, + longitude: 83.393749999995748, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121470520', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.452083333332041, + longitude: 83.931249999995828, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121470530', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.452083333332041, + longitude: 87.9104166666624, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121470540', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.447916666665375, + longitude: 86.568749999995816, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121470580', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.439583333331939, + longitude: 84.4062499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121470710', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.435416666665333, + longitude: 87.322916666662479, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121470810', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.418749999998624, + longitude: 83.743749999995828, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121470960', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.406249999998749, + longitude: 85.422916666662445, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121471120', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.39791666666531, + longitude: 86.231249999995782, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121471240', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.39791666666531, + longitude: 87.28124999999585, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121471250', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.393749999998704, + longitude: 83.852083333329176, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121471290', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.377083333332, + longitude: 86.4395833333291, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121471550', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.343749999998639, + longitude: 83.352083333329119, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121471930', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.335416666665367, + longitude: 84.6104166666625, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121472030', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.318749999998715, + longitude: 85.206249999995862, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121472200', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.302083333332007, + longitude: 86.239583333329051, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121472410', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.2979166666654, + longitude: 86.443749999995759, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121472460', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.281249999998693, + longitude: 87.935416666662377, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121472710', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.277083333332087, + longitude: 85.185416666662547, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121472790', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.272916666665253, + longitude: 85.627083333329153, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121472840', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.268749999998647, + longitude: 86.106249999995725, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121472900', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.256249999998769, + longitude: 85.743749999995771, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121473000', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.256249999998769, + longitude: 85.868749999995828, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121473010', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.21041666666531, + longitude: 84.772916666662525, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121473600', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.177083333332121, + longitude: 87.010416666662366, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121474020', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.160416666665469, + longitude: 86.806249999995714, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121474230', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.156249999998639, + longitude: 87.277083333329188, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121474270', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.15208333333203, + longitude: 85.18958333332921, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121474320', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.139583333331927, + longitude: 86.622916666662491, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121474500', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.122916666665446, + longitude: 87.243749999995828, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121474770', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.118749999998613, + longitude: 86.085416666662411, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121474860', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.118749999998613, + longitude: 86.518749999995748, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121474870', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.118749999998613, + longitude: 87.056249999995828, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121474880', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.102083333332128, + longitude: 85.214583333329131, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121475150', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.085416666665424, + longitude: 87.114583333329165, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121475370', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.05624999999867, + longitude: 85.572916666662479, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121475800', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.018749999998704, + longitude: 85.622916666662491, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121476290', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.010416666665435, + longitude: 85.352083333329062, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121476450', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 27.006249999998658, + longitude: 85.110416666662388, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121476510', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.993749999998727, + longitude: 85.022916666662468, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121476610', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.968749999998806, + longitude: 87.435416666662491, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121476970', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.947916666665321, + longitude: 87.385416666662422, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121477240', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.935416666665446, + longitude: 86.152083333329188, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121477330', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.9229166666654, + longitude: 87.302083333329165, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121477490', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.914583333332128, + longitude: 87.768749999995691, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121477630', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.9104166666653, + longitude: 85.0645833333291, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121477710', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.893749999998647, + longitude: 85.497916666662434, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121477930', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.877083333332109, + longitude: 85.577083333329085, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121478190', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.864583333332064, + longitude: 85.177083333329108, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121478420', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.839583333332143, + longitude: 85.843749999995737, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121478790', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.797916666665287, + longitude: 86.668749999995725, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121479250', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.793749999998681, + longitude: 86.822916666662366, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121479320', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.789583333332075, + longitude: 86.143749999995748, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121479390', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.768749999998761, + longitude: 86.714583333329188, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121479630', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.768749999998761, + longitude: 86.8812499999957, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121479640', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.760416666665321, + longitude: 87.864583333329165, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121479780', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.739583333332007, + longitude: 86.056249999995828, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121480080', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.693749999998715, + longitude: 85.956249999995748, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121480620', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.693749999998715, + longitude: 87.618749999995828, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121480630', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.652083333332087, + longitude: 86.447916666662366, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121481120', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.635416666665435, + longitude: 86.3437499999958, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121481390', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.6312499999986, + longitude: 87.87708333332904, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121481430', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.606249999998681, + longitude: 86.206249999995862, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121481830', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.572916666665321, + longitude: 87.393749999995634, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121482220', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.547916666665344, + longitude: 87.177083333329108, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121482480', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.543749999998731, + longitude: 86.481249999995725, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121482580', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.535416666665469, + longitude: 87.097916666662456, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121482710', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.497916666665279, + longitude: 87.585416666662468, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121483180', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.477083333331962, + longitude: 86.6270833333291, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121483530', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.468749999998749, + longitude: 86.835416666662468, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121483650', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.422916666665451, + longitude: 86.739583333329108, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121484200', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.402083333332143, + longitude: 87.702083333329085, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121484460', + qualityVerified: false, + hasModel: true, + }, + { + location: { + latitude: 26.385416666665321, + longitude: 88.047916666662388, + }, + siteName: '', + source: 'HYBAS', + river: '', + gaugeId: 'hybas_4121484710', + qualityVerified: false, + hasModel: true, + }, + ], +}; + +export const generateGFHGaugeMetadataResponse = (config: GfhStationDetails) => { + const finalResponse = { + gaugeModels: config?.STATION_LOCATIONS_DETAILS?.map((station: any) => { + return { + gaugeId: station.RIVER_GAUGE_ID || '-', + thresholds: { + warningLevel: station.THRESHOLDS?.WARNING_LEVEL || 0, + dangerLevel: station.THRESHOLDS?.DANGER_LEVEL || 0, + extremeDangerLevel: station.THRESHOLDS?.EXTREME_DANGER_LEVEL || 0, + }, + gaugeValueUnit: 'CUBIC_METERS_PER_SECOND', + qualityVerified: false, + gaugeModelId: + 'd2f368fdc4e48e772c52779eaf76bd0c947a60aff1c0f5000e136934d94b8db3', + }; + }), + }; + return finalResponse; +}; + +export const generateGFHForecastResponse = (config: GfhStationDetails) => { + const finalResponse = { + forecasts: config?.STATION_LOCATIONS_DETAILS?.reduce( + (acc: any, station: any) => { + acc[station.RIVER_GAUGE_ID] = { + forecasts: [ + { + issuedTime: '2025-10-28T06:48:39.825275Z', + forecastRanges: [ + { + value: 5.35258674621582, + forecastStartTime: '2025-10-26T00:00:00Z', + forecastEndTime: '2025-10-27T00:00:00Z', + }, + { + value: 5.351738929748535, + forecastStartTime: '2025-10-27T00:00:00Z', + forecastEndTime: '2025-10-28T00:00:00Z', + }, + { + value: 5.337410926818848, + forecastStartTime: '2025-10-28T00:00:00Z', + forecastEndTime: '2025-10-29T00:00:00Z', + }, + { + value: 5.24284553527832, + forecastStartTime: '2025-10-29T00:00:00Z', + forecastEndTime: '2025-10-30T00:00:00Z', + }, + { + value: 5.213508129119873, + forecastStartTime: '2025-10-30T00:00:00Z', + forecastEndTime: '2025-10-31T00:00:00Z', + }, + { + value: 5.0974345207214355, + forecastStartTime: '2025-10-31T00:00:00Z', + forecastEndTime: '2025-11-01T00:00:00Z', + }, + { + value: 5.042622089385986, + forecastStartTime: '2025-11-01T00:00:00Z', + forecastEndTime: '2025-11-02T00:00:00Z', + }, + { + value: 4.906806945800781, + forecastStartTime: '2025-11-02T00:00:00Z', + forecastEndTime: '2025-11-03T00:00:00Z', + }, + ], + gaugeId: station.RIVER_GAUGE_ID, + }, + { + issuedTime: '2025-10-29T06:51:50.625894Z', + forecastRanges: [ + { + value: 5.4788336753845215, + forecastStartTime: '2025-10-27T00:00:00Z', + forecastEndTime: '2025-10-28T00:00:00Z', + }, + { + value: 5.431178092956543, + forecastStartTime: '2025-10-28T00:00:00Z', + forecastEndTime: '2025-10-29T00:00:00Z', + }, + { + value: 5.311497211456299, + forecastStartTime: '2025-10-29T00:00:00Z', + forecastEndTime: '2025-10-30T00:00:00Z', + }, + { + value: 5.322411060333252, + forecastStartTime: '2025-10-30T00:00:00Z', + forecastEndTime: '2025-10-31T00:00:00Z', + }, + { + value: 5.242835521697998, + forecastStartTime: '2025-10-31T00:00:00Z', + forecastEndTime: '2025-11-01T00:00:00Z', + }, + { + value: 5.158617973327637, + forecastStartTime: '2025-11-01T00:00:00Z', + forecastEndTime: '2025-11-02T00:00:00Z', + }, + { + value: 5.051015853881836, + forecastStartTime: '2025-11-02T00:00:00Z', + forecastEndTime: '2025-11-03T00:00:00Z', + }, + { + value: 4.9244184494018555, + forecastStartTime: '2025-11-03T00:00:00Z', + forecastEndTime: '2025-11-04T00:00:00Z', + }, + ], + gaugeId: station.RIVER_GAUGE_ID, + }, + { + issuedTime: '2025-10-30T06:53:50.057581Z', + forecastRanges: [ + { + value: 5.578550815582275, + forecastStartTime: '2025-10-28T00:00:00Z', + forecastEndTime: '2025-10-29T00:00:00Z', + }, + { + value: 5.489238739013672, + forecastStartTime: '2025-10-29T00:00:00Z', + forecastEndTime: '2025-10-30T00:00:00Z', + }, + { + value: 5.590737819671631, + forecastStartTime: '2025-10-30T00:00:00Z', + forecastEndTime: '2025-10-31T00:00:00Z', + }, + { + value: 5.408641815185547, + forecastStartTime: '2025-10-31T00:00:00Z', + forecastEndTime: '2025-11-01T00:00:00Z', + }, + { + value: 5.318427085876465, + forecastStartTime: '2025-11-01T00:00:00Z', + forecastEndTime: '2025-11-02T00:00:00Z', + }, + { + value: 5.171968460083008, + forecastStartTime: '2025-11-02T00:00:00Z', + forecastEndTime: '2025-11-03T00:00:00Z', + }, + { + value: 5.050614356994629, + forecastStartTime: '2025-11-03T00:00:00Z', + forecastEndTime: '2025-11-04T00:00:00Z', + }, + { + value: 4.952243328094482, + forecastStartTime: '2025-11-04T00:00:00Z', + forecastEndTime: '2025-11-05T00:00:00Z', + }, + ], + gaugeId: station.RIVER_GAUGE_ID, + }, + { + issuedTime: '2025-10-31T06:53:28.993171Z', + forecastRanges: [ + { + value: 5.5700554847717285, + forecastStartTime: '2025-10-29T00:00:00Z', + forecastEndTime: '2025-10-30T00:00:00Z', + }, + { + value: 6.064761638641357, + forecastStartTime: '2025-10-30T00:00:00Z', + forecastEndTime: '2025-10-31T00:00:00Z', + }, + { + value: 5.759688854217529, + forecastStartTime: '2025-10-31T00:00:00Z', + forecastEndTime: '2025-11-01T00:00:00Z', + }, + { + value: 5.5250163078308105, + forecastStartTime: '2025-11-01T00:00:00Z', + forecastEndTime: '2025-11-02T00:00:00Z', + }, + { + value: 5.366203784942627, + forecastStartTime: '2025-11-02T00:00:00Z', + forecastEndTime: '2025-11-03T00:00:00Z', + }, + { + value: 5.222720146179199, + forecastStartTime: '2025-11-03T00:00:00Z', + forecastEndTime: '2025-11-04T00:00:00Z', + }, + { + value: 5.122296333312988, + forecastStartTime: '2025-11-04T00:00:00Z', + forecastEndTime: '2025-11-05T00:00:00Z', + }, + { + value: 4.999033451080322, + forecastStartTime: '2025-11-05T00:00:00Z', + forecastEndTime: '2025-11-06T00:00:00Z', + }, + ], + gaugeId: station.RIVER_GAUGE_ID, + }, + { + issuedTime: '2025-11-01T07:01:06.083690Z', + forecastRanges: [ + { + value: 5.966923713684082, + forecastStartTime: '2025-10-30T00:00:00Z', + forecastEndTime: '2025-10-31T00:00:00Z', + }, + { + value: 5.7330546379089355, + forecastStartTime: '2025-10-31T00:00:00Z', + forecastEndTime: '2025-11-01T00:00:00Z', + }, + { + value: 5.503265380859375, + forecastStartTime: '2025-11-01T00:00:00Z', + forecastEndTime: '2025-11-02T00:00:00Z', + }, + { + value: 5.365660190582275, + forecastStartTime: '2025-11-02T00:00:00Z', + forecastEndTime: '2025-11-03T00:00:00Z', + }, + { + value: 5.187310695648193, + forecastStartTime: '2025-11-03T00:00:00Z', + forecastEndTime: '2025-11-04T00:00:00Z', + }, + { + value: 5.074647903442383, + forecastStartTime: '2025-11-04T00:00:00Z', + forecastEndTime: '2025-11-05T00:00:00Z', + }, + { + value: 4.974766254425049, + forecastStartTime: '2025-11-05T00:00:00Z', + forecastEndTime: '2025-11-06T00:00:00Z', + }, + { + value: 4.871321201324463, + forecastStartTime: '2025-11-06T00:00:00Z', + forecastEndTime: '2025-11-07T00:00:00Z', + }, + ], + gaugeId: station.RIVER_GAUGE_ID, + }, + { + issuedTime: '2025-11-02T07:18:05.885056Z', + forecastRanges: [ + { + value: 5.782345294952393, + forecastStartTime: '2025-10-31T00:00:00Z', + forecastEndTime: '2025-11-01T00:00:00Z', + }, + { + value: 5.665348052978516, + forecastStartTime: '2025-11-01T00:00:00Z', + forecastEndTime: '2025-11-02T00:00:00Z', + }, + { + value: 5.412362098693848, + forecastStartTime: '2025-11-02T00:00:00Z', + forecastEndTime: '2025-11-03T00:00:00Z', + }, + { + value: 5.249450206756592, + forecastStartTime: '2025-11-03T00:00:00Z', + forecastEndTime: '2025-11-04T00:00:00Z', + }, + { + value: 5.097894668579102, + forecastStartTime: '2025-11-04T00:00:00Z', + forecastEndTime: '2025-11-05T00:00:00Z', + }, + { + value: 4.994709491729736, + forecastStartTime: '2025-11-05T00:00:00Z', + forecastEndTime: '2025-11-06T00:00:00Z', + }, + { + value: 4.906863212585449, + forecastStartTime: '2025-11-06T00:00:00Z', + forecastEndTime: '2025-11-07T00:00:00Z', + }, + { + value: 4.829066753387451, + forecastStartTime: '2025-11-07T00:00:00Z', + forecastEndTime: '2025-11-08T00:00:00Z', + }, + ], + gaugeId: station.RIVER_GAUGE_ID, + }, + { + issuedTime: '2025-11-03T06:56:19.916027Z', + forecastRanges: [ + { + value: 5.647912979125977, + forecastStartTime: '2025-11-01T00:00:00Z', + forecastEndTime: '2025-11-02T00:00:00Z', + }, + { + value: 5.469335079193115, + forecastStartTime: '2025-11-02T00:00:00Z', + forecastEndTime: '2025-11-03T00:00:00Z', + }, + { + value: 5.2439775466918945, + forecastStartTime: '2025-11-03T00:00:00Z', + forecastEndTime: '2025-11-04T00:00:00Z', + }, + { + value: 5.1063008308410645, + forecastStartTime: '2025-11-04T00:00:00Z', + forecastEndTime: '2025-11-05T00:00:00Z', + }, + { + value: 4.980710506439209, + forecastStartTime: '2025-11-05T00:00:00Z', + forecastEndTime: '2025-11-06T00:00:00Z', + }, + { + value: 4.9060773849487305, + forecastStartTime: '2025-11-06T00:00:00Z', + forecastEndTime: '2025-11-07T00:00:00Z', + }, + { + value: 4.826399803161621, + forecastStartTime: '2025-11-07T00:00:00Z', + forecastEndTime: '2025-11-08T00:00:00Z', + }, + { + value: 4.75192928314209, + forecastStartTime: '2025-11-08T00:00:00Z', + forecastEndTime: '2025-11-09T00:00:00Z', + }, + ], + gaugeId: station.RIVER_GAUGE_ID, + }, + { + issuedTime: '2025-11-03T18:56:29.865967Z', + forecastRanges: [ + { + value: 5.4981279373168945, + forecastStartTime: '2025-11-02T00:00:00Z', + forecastEndTime: '2025-11-03T00:00:00Z', + }, + { + value: 5.377904415130615, + forecastStartTime: '2025-11-03T00:00:00Z', + forecastEndTime: '2025-11-04T00:00:00Z', + }, + { + value: 5.2324700355529785, + forecastStartTime: '2025-11-04T00:00:00Z', + forecastEndTime: '2025-11-05T00:00:00Z', + }, + { + value: 5.121635913848877, + forecastStartTime: '2025-11-05T00:00:00Z', + forecastEndTime: '2025-11-06T00:00:00Z', + }, + { + value: 5.041450500488281, + forecastStartTime: '2025-11-06T00:00:00Z', + forecastEndTime: '2025-11-07T00:00:00Z', + }, + { + value: 4.8880438804626465, + forecastStartTime: '2025-11-07T00:00:00Z', + forecastEndTime: '2025-11-08T00:00:00Z', + }, + { + value: 4.789149761199951, + forecastStartTime: '2025-11-08T00:00:00Z', + forecastEndTime: '2025-11-09T00:00:00Z', + }, + { + value: 4.729656219482422, + forecastStartTime: '2025-11-09T00:00:00Z', + forecastEndTime: '2025-11-10T00:00:00Z', + }, + ], + gaugeId: station.RIVER_GAUGE_ID, + }, + ], + }; + return acc; + }, + {}, + ), + }; + + return finalResponse; +}; diff --git a/apps/mock-api/src/data/glofas/raw-response.ts b/apps/mock-api/src/data/glofas/raw-response.ts new file mode 100644 index 0000000..27b76a0 --- /dev/null +++ b/apps/mock-api/src/data/glofas/raw-response.ts @@ -0,0 +1,1030 @@ +export const glofasRawResponseTemplate = ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Station IDCountryBasinRiverStation NamePoint IDDrainage Area [km2]Longitude [Deg]Latitude [Deg]LISFLOOD Drainage Area [km2]LISFLOOD X [Deg]LISFLOOD Y [Deg]
G4475{{country}}{{basin}}{{river}}{{stationName}}SI001169NA{{longitude}}{{latitude}}53,99887.12526.825
+ + + + + + + + + + + + + + + + + + +
Point Forecast
Forecast DateMaximum probability (2 yr / 5 yr / 20 yr)Alert levelMax probability step (earliest)Discharge tendencyPeak forecasted
{{forecastDate}}{{probability}} / {{probability}} / {{probability}}InactiveNo DataDischarge tendencyin 1 day (on 2025-10-31)

>>Open/Close GloFAS Forecast + images


+
+ Discharge HydrographDischarge Hydrograph
Upstream PrecipitationUpstream Precipitation
Upstream SnowmeltUpstream Snowmelt
Average TemperatureAverage Temperature
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Forecasts Overview (2025-10-30 00:00)
Forecast Type303101020304050607080910111213
IFS ENS
AIFS Single*
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AIFS Single
Forecast Day242526272829303112345678910111213
2025-10-30
2025-10-29
2025-10-28
2025-10-27
2025-10-26
2025-10-25
2025-10-24
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IFS ENS > 2 yr RP
Forecast Day242526272829303112345678910111213
2025-10-302
2025-10-29
2025-10-28
2025-10-27
2025-10-262
2025-10-254
2025-10-24644
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IFS ENS > 5 yr RP
Forecast Day242526272829303112345678910111213
2025-10-30
2025-10-29
2025-10-28
2025-10-27
2025-10-26
2025-10-25
2025-10-242
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IFS ENS > 20 yr RP
Forecast Day242526272829303112345678910111213
2025-10-30
2025-10-29
2025-10-28
2025-10-27
2025-10-26
2025-10-25
2025-10-24
+`; diff --git a/apps/mock-api/src/forecast/forecast.controller.ts b/apps/mock-api/src/forecast/forecast.controller.ts new file mode 100644 index 0000000..0168a68 --- /dev/null +++ b/apps/mock-api/src/forecast/forecast.controller.ts @@ -0,0 +1,43 @@ +import { Body, Controller, Get, Post, Query } from '@nestjs/common'; +import { ApiOperation, ApiTags } from '@nestjs/swagger'; +import { ForecastService } from './forecast.service'; + +@Controller('forecast') +@ApiTags('Forecast') +export class ForecastController { + constructor(private readonly forecastService: ForecastService) {} + + @Get('river') + getRiverForecast() { + return this.forecastService.getRiverForecast(); + } + + @Get('glofas') + async getGlofasForecast(@Query() query: any) { + return this.forecastService.getGlofasForecast(query); + } + + @Post('gauges:searchGaugesByArea') + @ApiOperation({ + description: 'Fetch GFH gauges within a specified area.', + }) + async getGFHGauges(@Body() body: any) { + return this.forecastService.getGFHGauges(); + } + + @Get('gaugeModels:batchGet') + @ApiOperation({ + description: 'Fetch GFH gauge metadata.', + }) + async getGFHGaugeMetadata(@Query() query: any) { + return this.forecastService.getGFHGaugeMetadata(); + } + + @Get('gauges:queryGaugeForecasts') + @ApiOperation({ + description: 'Fetch GFH gauge forecasts.', + }) + async getGFHGaugeForecast(@Query() query: any) { + return this.forecastService.getGFHGaugeForecast(); + } +} diff --git a/apps/mock-api/src/forecast/forecast.module.ts b/apps/mock-api/src/forecast/forecast.module.ts new file mode 100644 index 0000000..d22d60f --- /dev/null +++ b/apps/mock-api/src/forecast/forecast.module.ts @@ -0,0 +1,11 @@ +import { Module } from '@nestjs/common'; +import { ForecastService } from './forecast.service'; +import { ForecastController } from './forecast.controller'; + +@Module({ + imports: [], + controllers: [ForecastController], + providers: [ForecastService], + exports: [ForecastService], +}) +export class ForecastModule {} diff --git a/apps/mock-api/src/forecast/forecast.service.ts b/apps/mock-api/src/forecast/forecast.service.ts new file mode 100644 index 0000000..8b61a3d --- /dev/null +++ b/apps/mock-api/src/forecast/forecast.service.ts @@ -0,0 +1,164 @@ +import { Injectable, Logger, HttpException, HttpStatus } from '@nestjs/common'; +import { demoRiverForecast } from 'src/data/dhm'; +import { PrismaService } from '@lib/database'; +import { glofasRawResponseTemplate } from 'src/data/glofas/raw-response'; +import { DataSourceSettings } from '../types/data-source'; +import { parseDate } from '../utils/date'; +import { + generateGFHForecastResponse, + generateGFHGaugeMetadataResponse, + gfhGauges, +} from 'src/data/gfh'; + +@Injectable() +export class ForecastService { + logger = new Logger(ForecastService.name); + constructor(private readonly prisma: PrismaService) {} + + private riverForecast = demoRiverForecast; + private glofasForecast = glofasRawResponseTemplate; + + async getRiverForecast(): Promise { + this.logger.log('Fetching river forecast'); + return new Promise((resolve, reject) => { + const shouldFail = Math.random() < 0.1; // 10% chance to fail + setTimeout(() => { + if (shouldFail) { + this.logger.error('Failed to fetch river forecast'); + // Reject with a proper HttpException so Nest can return the provided message + reject( + new HttpException( + { message: 'Network error: failed to fetch river forecast' }, + HttpStatus.SERVICE_UNAVAILABLE, + ), + ); + } else { + resolve(this.riverForecast); + } + }, 1000); + }); + } + + async getGlofasForecast(query: any) { + this.logger.log('Fetching GloFAS forecast'); + try { + const glofasSettings = await this.prisma.setting.findUnique({ + where: { name: 'DATASOURCE' }, + }); + + if (!glofasSettings) { + this.logger.warn('No GloFAS settings found, using default response'); + return 'No data'; + } + + const gfhArray = glofasSettings.value as DataSourceSettings; + + const gfhStationData = gfhArray?.GLOFAS?.[0]; + + const dynamicResponse = this.generateDynamicGlofasResponse( + gfhStationData, + query, + ); + + this.logger.log('Returning dynamic GloFAS forecast data'); + return dynamicResponse; + } catch (error) { + this.logger.error( + 'Error fetching GloFAS settings, using default response', + error, + ); + } + } + + private generateDynamicGlofasResponse(glofasData: any, query?: any) { + const template = glofasRawResponseTemplate; + + const replacements: Record = { + stationId: `glofasData.STATION_ID`, + country: 'Nepal', + basin: 'Na', + river: 'Doda', + longitude: '80.434', + latitude: '28,853', + stationName: glofasData.LOCATION, + forecastDate: parseDate(query?.TIME), + probability: glofasData.PROBABILITY, + }; + + let dynamicHTML = template; + for (const [key, value] of Object.entries(replacements)) { + const regex = new RegExp(`{{${key}}}`, 'g'); + dynamicHTML = dynamicHTML.replace(regex, String(value)); + } + + return { + content: { + 'Reporting Points': { + layer_name_index: 'Reporting Points', + point: dynamicHTML, + name: `G10165; Basin: Nepal; Station: Na;;`, + }, + }, + }; + } + + async getGFHGauges() { + this.logger.log('Fetching GFH Gauges'); + return gfhGauges; + } + + private async getGFHConfig() { + this.logger.log('Fetching GFH Data Source Configuration'); + try { + const dataSourceSettings = await this.prisma.setting.findUnique({ + where: { name: 'DATASOURCE' }, + }); + + if (!dataSourceSettings) { + const message = 'Data source settings not found'; + this.logger.warn(message); + return { error: message }; + } + + const gfhConfig = (dataSourceSettings.value as DataSourceSettings) + .GFH?.[0]; + + if (!gfhConfig) { + const message = 'GFH configuration not found'; + this.logger.warn(message); + return { error: message }; + } + + return { gfhConfig }; + } catch (err) { + this.logger.error('Error fetching GFH configuration', err); + return { error: 'Internal error while fetching GFH configuration' }; + } + } + + async getGFHGaugeMetadata() { + this.logger.log('Fetching GFH Gauge Metadata'); + try { + const { gfhConfig, error } = await this.getGFHConfig(); + if (error) return { data: null, message: error }; + + return generateGFHGaugeMetadataResponse(gfhConfig); + } catch (err) { + this.logger.error('Error generating GFH gauge metadata', err); + return { data: null, message: 'Failed to fetch gauge metadata' }; + } + } + + async getGFHGaugeForecast() { + this.logger.log('Fetching GFH Gauge Forecast'); + try { + const { gfhConfig, error } = await this.getGFHConfig(); + if (error) return { data: null, message: error }; + + return generateGFHForecastResponse(gfhConfig); + } catch (err) { + this.logger.error('Error generating GFH gauge forecast', err); + return { data: null, message: 'Failed to fetch gauge forecast' }; + } + } +} diff --git a/apps/mock-api/src/helpers/wiston.logger.ts b/apps/mock-api/src/helpers/wiston.logger.ts new file mode 100644 index 0000000..9b04f20 --- /dev/null +++ b/apps/mock-api/src/helpers/wiston.logger.ts @@ -0,0 +1,52 @@ +import { createLogger, format, transports } from 'winston'; + +// custom log display format +const customFormat = format.printf((info) => { + return `${info.timestamp} ${info.level}: [${info.context || 'Rahat Triggers'}] ${ + info.message + }`; +}); + +const options = { + file: { + filename: '.log/error.log', + level: 'error', + }, + console: { + level: 'silly', + }, +}; + +// for development environment +const devLogger = { + format: format.combine( + format((info) => ({ ...info, level: info.level.toUpperCase() }))(), + format.colorize({ all: true }), + format.timestamp({ format: 'YYYY-MM-DD, HH:mm:ss' }), + format.errors({ stack: true }), + customFormat, + ), + transports: [new transports.Console(options.console)], +}; + +// for production environment +const prodLogger = { + format: format.combine( + format.timestamp(), + format.errors({ stack: true }), + format.json(), + ), + transports: [ + new transports.File(options.file), + new transports.File({ + filename: '.log/combine.log', + level: 'info', + }), + ], +}; + +// export log instance based on the current environment +const envLogger = + process.env.NODE_ENV === 'production' ? prodLogger : devLogger; + +export const loggerInstance = createLogger(envLogger); diff --git a/apps/mock-api/src/main.ts b/apps/mock-api/src/main.ts new file mode 100644 index 0000000..24db92a --- /dev/null +++ b/apps/mock-api/src/main.ts @@ -0,0 +1,52 @@ +import { NestFactory } from '@nestjs/core'; +import { AppModule } from './app.module'; +import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger'; +import { Logger, ValidationPipe } from '@nestjs/common'; +import { AllExceptionsFilter } from './all-exceptions.filter'; +import { PrismaClientExceptionFilter } from '@lib/database'; +import { WinstonModule } from 'nest-winston'; +import { loggerInstance } from './helpers/wiston.logger'; + +async function bootstrap() { + const app = await NestFactory.create(AppModule, { + logger: WinstonModule.createLogger({ + instance: loggerInstance, + }), + }); + + const globalPrefix = 'v1'; + app.setGlobalPrefix(globalPrefix); + app.enableCors(); + app.useGlobalPipes( + new ValidationPipe({ + whitelist: true, + transform: true, + transformOptions: { enableImplicitConversion: true }, + }), + ); + + app.useGlobalFilters( + new AllExceptionsFilter(), + new PrismaClientExceptionFilter(), + ); + + const config = new DocumentBuilder() + .setTitle('Rahat Triggers') + .setDescription('The Rahat Triggers API description') + .setVersion('1.0') + .addTag('Triggers') + .build(); + + const documentFactory = () => SwaggerModule.createDocument(app, config); + + SwaggerModule.setup('swagger', app, documentFactory); + + const port = process.env.PORT ?? 3005; + await app.listen(port); + + Logger.warn( + `Application is running on: http://localhost:${port}/${globalPrefix}`, + ); + Logger.warn(`Swagger UI: http://localhost:${port}/swagger`); +} +bootstrap(); diff --git a/apps/mock-api/src/triggers/dto/trigger.dto.ts b/apps/mock-api/src/triggers/dto/trigger.dto.ts new file mode 100644 index 0000000..b536149 --- /dev/null +++ b/apps/mock-api/src/triggers/dto/trigger.dto.ts @@ -0,0 +1,34 @@ +import { IsString, IsJSON, IsOptional, IsBoolean } from 'class-validator'; + +export class TriggerDto { + @IsString() + repeatKey: string; + + @IsString() + repeatEvery: string; + + @IsJSON() + triggerStatement: any; + + @IsString() + @IsOptional() + triggerDocuments?: any; + + @IsString() + notes: string; + + @IsString() + title: string; + + @IsString() + description: string; + + @IsBoolean() + isMandatory: boolean; + + @IsBoolean() + isTriggered: boolean; + + @IsBoolean() + isDeleted: boolean; +} diff --git a/apps/mock-api/src/triggers/trigger.module.ts b/apps/mock-api/src/triggers/trigger.module.ts new file mode 100644 index 0000000..3718c47 --- /dev/null +++ b/apps/mock-api/src/triggers/trigger.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { TriggersController } from './triggers.controller'; +import { TriggersService } from './trigger.service'; + +@Module({ + imports: [], + controllers: [TriggersController], + providers: [TriggersService], +}) +export class TriggersModule {} diff --git a/apps/mock-api/src/triggers/trigger.service.ts b/apps/mock-api/src/triggers/trigger.service.ts new file mode 100644 index 0000000..ce4137e --- /dev/null +++ b/apps/mock-api/src/triggers/trigger.service.ts @@ -0,0 +1,87 @@ +import { Prisma, PrismaService } from '@lib/database'; +import { Injectable, Logger } from '@nestjs/common'; +import { TriggerDto } from './dto/trigger.dto'; +import { Parser } from 'expr-eval'; + +@Injectable() +export class TriggersService { + private readonly logger = new Logger(TriggersService.name); + constructor(private readonly prismaService: PrismaService) {} + + async findAll() { + this.logger.log('Finding all triggers'); + return this.prismaService.trigger.findMany(); + } + + async findOne(id: number) { + this.logger.log(`Finding trigger with id: ${id}`); + return this.prismaService.trigger.findUnique({ + where: { id }, + }); + } + + async create(data: TriggerDto) { + // Payload example + /* + { + "repeatKey": "asfadf", + "repeatEvery": "1", + "triggerStatement": { + "phase": "Readness", + "value": 5, + "source": "water_level_m", + "operator": ">=", + "expression": "warning_level >= 5", + "riverBasin": "Doda", + "sourceSubType": "warning_level" + }, + "triggerDocuments": null, + "notes": "asdfasdfasf", + "title": "Titile", + "description": "this is atest", + "phaseId": null, + "source": null, + "isMandatory": false, + "isTriggered": false, + "isDeleted": false, + "isDailyMonitored": false, + "createdBy": null, + "triggeredBy": null, + "transactionHash": null, + "triggeredAt": null, + } + */ + this.logger.log('Creating trigger', data); + const triggerStatement = JSON.parse(data.triggerStatement) as { + expression: string; + source: string; + operator: string; + value: number; + sourceSubType: string; + }; + console.log('Trigger statement', triggerStatement); + + const result = Parser.evaluate(triggerStatement.expression, { + [triggerStatement.sourceSubType]: 90, + }); + + console.log('Result', result); + + return this.prismaService.trigger.create({ + data: { + ...data, + triggerStatement: triggerStatement, + }, + }); + } + + async update(id: number, data: Prisma.TriggerUpdateInput) { + this.logger.log(`Updating trigger with id: ${id}`, data); + return this.prismaService.trigger.update({ where: { id }, data }); + } + + async delete(id: number) { + this.logger.log(`Deleting trigger with id: ${id}`); + return this.prismaService.trigger.delete({ where: { id } }); + } +} diff --git a/apps/mock-api/src/triggers/triggers.controller.ts b/apps/mock-api/src/triggers/triggers.controller.ts new file mode 100644 index 0000000..a4e10a6 --- /dev/null +++ b/apps/mock-api/src/triggers/triggers.controller.ts @@ -0,0 +1,52 @@ +import { ApiResponse, ApiTags, ApiOperation } from '@nestjs/swagger'; +import { Controller, Param } from '@nestjs/common'; +import { Get, Post, Patch, Delete, Body } from '@nestjs/common'; +import { TriggersService } from './trigger.service'; +import { Prisma } from '@lib/database'; +import { TriggerDto } from './dto/trigger.dto'; + +@ApiTags('triggers') +@Controller('triggers') +export class TriggersController { + constructor(private readonly triggersService: TriggersService) {} + + @Get() + @ApiOperation({ summary: 'Get all triggers' }) + @ApiResponse({ status: 200, description: 'Triggers retrieved successfully' }) + findAll() { + return this.triggersService.findAll(); + } + + @Get(':id') + @ApiOperation({ summary: 'Get a trigger by ID' }) + @ApiResponse({ status: 200, description: 'Trigger retrieved successfully' }) + @ApiResponse({ status: 404, description: 'Trigger not found' }) + findOne(@Param('id') id: number) { + return this.triggersService.findOne(id); + } + + @Post() + @ApiOperation({ summary: 'Create a new trigger' }) + @ApiResponse({ status: 201, description: 'Trigger created successfully' }) + @ApiResponse({ status: 400, description: 'Bad request' }) + create(@Body() data: TriggerDto) { + return this.triggersService.create(data); + } + + @Patch(':id') + @ApiOperation({ summary: 'Update a trigger by ID' }) + @ApiResponse({ status: 200, description: 'Trigger updated successfully' }) + @ApiResponse({ status: 400, description: 'Bad request' }) + @ApiResponse({ status: 404, description: 'Trigger not found' }) + update(@Param('id') id: number, @Body() data: Prisma.TriggerUpdateInput) { + return this.triggersService.update(id, data); + } + + @Delete(':id') + @ApiOperation({ summary: 'Delete a trigger by ID' }) + @ApiResponse({ status: 200, description: 'Trigger deleted successfully' }) + @ApiResponse({ status: 404, description: 'Trigger not found' }) + delete(@Param('id') id: number) { + return this.triggersService.delete(id); + } +} diff --git a/apps/mock-api/src/types/data-source.ts b/apps/mock-api/src/types/data-source.ts new file mode 100644 index 0000000..1c82c8b --- /dev/null +++ b/apps/mock-api/src/types/data-source.ts @@ -0,0 +1,243 @@ +// export interface RiverStationItem { +// name: string; +// id: number; +// stationIndex: string; +// basin: string; +// district: string; +// latitude: number | null; +// longitude: number | null; +// series_id: number; +// waterLevel: number | null; +// status: string; +// warning_level: string; +// danger_level: string; +// steady: string; +// onm: string; +// description: string; +// elevation: number; +// images: Array>; +// tags: string[]; +// } + +// export type RainfallStationItem = { +// id: number; +// series_id: number; +// stationIndex: string; +// name: string; +// status: string; +// basin: string; +// district: string; +// description: string; +// longitude: number; +// latitude: number; +// value: number | null; +// interval: number | null; +// blink: boolean; +// }; + +// export interface RiverWaterHistoryItem { +// datetime: string; +// value: number; +// max?: number; +// min?: number; +// } + +// export interface RiverStationData extends RiverStationItem { +// history?: RiverWaterHistoryItem[]; +// } + +// export interface RainfallStationData extends RainfallStationItem { +// history?: RiverWaterHistoryItem[]; +// } + +// export interface gfhStationDetails { +// riverBasin: string; +// source: string; +// latitude: number; +// longitude: number; +// riverGaugeId: string; +// stationName: string; +// warningLevel: string; +// dangerLevel: string; +// extremeDangerLevel: string; +// basinSize: number; +// forecastDate: string; +// } + +// export interface gfhStationData extends gfhStationDetails { +// history?: RiverWaterHistoryItem[]; +// } + +// export enum SourceDataTypeEnum { +// POINT = 1, +// HOURLY = 2, +// DAILY = 3, +// } + +// export type InputItem = +// | { +// Date: string; +// Point: number; +// } +// | { +// Date: string; +// Max: number; +// Min: number; +// Average: number; +// } +// | { +// Date: string; +// Hourly: number; +// Total: number; +// } +// | { +// Date: string; +// Daily: number; +// Total: number; +// }; + +// export interface NormalizedItem { +// datetime: string; +// value: number; +// max?: number; +// min?: number; +// } + +// export interface Point { +// x: number; +// y: number; +// } + +// interface Location { +// latitude: number; +// longitude: number; +// } + +// export interface GfhStationDetails { +// RIVER_BASIN: string; +// STATION_LOCATIONS_DETAILS: StationLoacationDetails[]; +// } + +// export interface StationLoacationDetails { +// LATITUDE: number; +// POINT_ID: string; +// RIVER_GAUGE_ID?: string; +// LONGITUDE: number; +// RIVER_NAME: string; +// STATION_ID: string; +// STATION_NAME: string; +// 'LISFLOOD_X_(DEG)': number; +// 'LISFLOOD_Y_[DEG]': number; +// LISFLOOD_DRAINAGE_AREA: number; +// } + +// export interface Gauge { +// gaugeId: string; +// location: Location; +// source?: string; +// qualityVerified?: boolean; +// [key: string]: any; +// } + +// interface ForecastRange { +// timeRange?: { +// startTime?: string; +// endTime?: string; +// }; +// trend?: string; +// severity?: string; +// [key: string]: any; +// } + +// export interface Forecast { +// issuedTime: string; +// forecastRanges: ForecastRange[]; +// [key: string]: any; +// } + +// export interface GaugeInfo { +// gaugeId: string; +// distance: number; +// source: string; +// gaugeLocation: Location; +// qualityVerified: boolean; +// } + +// export interface ProcessedForecast { +// issuedTime: string; +// forecastTimeRange: any; +// forecastTrend: string; +// severity: string; +// forecastRanges: ForecastRange[]; +// } + +// export interface GaugeData { +// model_metadata: any; +// all_forecasts: Forecast[]; +// latest_forecast: ProcessedForecast | null; +// } + +// export interface StationResult { +// gaugeId: string; +// distance_km: number; +// source: string; +// gaugeLocation: Location; +// qualityVerified: boolean; +// model_metadata: any; +// issuedTime: string | null; +// forecastTimeRange: any; +// forecastTrend: string; +// severity: string; +// forecasts: ForecastRange[]; +// total_forecasts_available: number; +// message?: string; +// } + +// export interface SearchGaugesRequest { +// regionCode: string; +// pageSize: number; +// includeNonQualityVerified: boolean; +// pageToken?: string; +// } + +// export interface SearchGaugesResponse { +// gauges: Gauge[]; +// nextPageToken?: string; +// } + +// export interface BatchGetResponse { +// gaugeModels: any[]; +// } + +// export interface QueryForecastsResponse { +// forecasts: Record; +// } +export interface GfhStationDetails { + RIVER_BASIN: string; + STATION_LOCATIONS_DETAILS: StationLoacationDetails[]; +} + +export interface StationLoacationDetails { + LATITUDE: number; + POINT_ID: string; + RIVER_GAUGE_ID?: string; + LONGITUDE: number; + RIVER_NAME: string; + STATION_ID: string; + STATION_NAME: string; + 'LISFLOOD_X_(DEG)': number; + 'LISFLOOD_Y_[DEG]': number; + LISFLOOD_DRAINAGE_AREA: number; + THRESHOLDS?: GfhThresholds; +} +interface GfhThresholds { + WARNING_LEVEL: number; + DANGER_LEVEL: number; + EXTREME_DANGER_LEVEL: number; +} + +export interface DataSourceSettings { + DHM?: any[]; + GFH?: any[]; + GLOFAS?: any[]; +} diff --git a/apps/mock-api/src/utils/date.ts b/apps/mock-api/src/utils/date.ts new file mode 100644 index 0000000..b846bf3 --- /dev/null +++ b/apps/mock-api/src/utils/date.ts @@ -0,0 +1,18 @@ +export function parseDate(dateString?: string): string { + if (!dateString) { + return new Date().toISOString().split('T')[0]; + } + + try { + const date = new Date(dateString); + + if (isNaN(date.getTime())) { + return new Date().toISOString().split('T')[0]; + } + + return date.toISOString().split('T')[0]; + } catch (error) { + console.error('Error parsing date:', error); + return new Date().toISOString().split('T')[0]; + } +} diff --git a/apps/mock-api/tsconfig.build.json b/apps/mock-api/tsconfig.build.json new file mode 100644 index 0000000..64f86c6 --- /dev/null +++ b/apps/mock-api/tsconfig.build.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] +} diff --git a/apps/mock-api/tsconfig.json b/apps/mock-api/tsconfig.json new file mode 100644 index 0000000..869278d --- /dev/null +++ b/apps/mock-api/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "@workspace/typescript-config/nestjs.json", + "compilerOptions": { + "baseUrl": "./", + "outDir": "./dist", + }, + "exclude": [ + "node_modules", + "dist" + ] +} diff --git a/packages/database/.env.example b/packages/database/.env.example index b2a34b4..2673ca6 100644 --- a/packages/database/.env.example +++ b/packages/database/.env.example @@ -1,5 +1,3 @@ - - DB_HOST=localhost DB_PORT=5555 DB_USERNAME=rahat diff --git a/packages/database/prisma/schema/migrations/20251128051042_add_schema_for_mock_forecast/migration.sql b/packages/database/prisma/schema/migrations/20251128051042_add_schema_for_mock_forecast/migration.sql deleted file mode 100644 index 32b03a9..0000000 --- a/packages/database/prisma/schema/migrations/20251128051042_add_schema_for_mock_forecast/migration.sql +++ /dev/null @@ -1,20 +0,0 @@ --- CreateSchema -CREATE SCHEMA IF NOT EXISTS "mock"; - --- CreateEnum -CREATE TYPE "mock"."MockSettingDataType" AS ENUM ('STRING', 'NUMBER', 'BOOLEAN', 'OBJECT'); - --- CreateTable -CREATE TABLE "mock"."tbl_settings" ( - "name" TEXT NOT NULL, - "value" JSONB NOT NULL, - "dataType" "public"."SettingDataType" NOT NULL, - "requiredFields" TEXT[], - "isReadOnly" BOOLEAN NOT NULL DEFAULT false, - "isPrivate" BOOLEAN NOT NULL DEFAULT true, - - CONSTRAINT "tbl_settings_pkey" PRIMARY KEY ("name") -); - --- CreateIndex -CREATE UNIQUE INDEX "tbl_settings_name_key" ON "mock"."tbl_settings"("name"); diff --git a/packages/database/prisma/schema/migrations/20251203082405_add_mock_api_database/migration.sql b/packages/database/prisma/schema/migrations/20251203082405_add_mock_api_database/migration.sql new file mode 100644 index 0000000..0237c6a --- /dev/null +++ b/packages/database/prisma/schema/migrations/20251203082405_add_mock_api_database/migration.sql @@ -0,0 +1,384 @@ +/* + Warnings: + + - You are about to drop the `tbl_activities` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `tbl_activity_categories` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `tbl_activity_managers` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `tbl_applications` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `tbl_daily_monitoring` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `tbl_phases` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `tbl_sources` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `tbl_sources_data` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `tbl_stats` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `tbl_trigger_history` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `tbl_triggers` table. If the table is not empty, all the data it contains will be lost. + - Changed the type of `dataType` on the `tbl_settings` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + +*/ +-- CreateEnum +CREATE TYPE "public"."ActivityStatus" AS ENUM ('NOT_STARTED', 'WORK_IN_PROGRESS', 'COMPLETED', 'DELAYED'); + +-- CreateEnum +CREATE TYPE "public"."ApplicationEnvironment" AS ENUM ('PRODUCTION', 'STAGING', 'DEVELOPMENT', 'TEST'); + +-- CreateEnum +CREATE TYPE "mock"."MockSettingDataType" AS ENUM ('STRING', 'NUMBER', 'BOOLEAN', 'OBJECT'); + +-- CreateEnum +CREATE TYPE "public"."Phases" AS ENUM ('PREPAREDNESS', 'READINESS', 'ACTIVATION'); + +-- CreateEnum +CREATE TYPE "public"."SettingDataType" AS ENUM ('STRING', 'NUMBER', 'BOOLEAN', 'OBJECT'); + +-- CreateEnum +CREATE TYPE "public"."SourceType" AS ENUM ('RAINFALL', 'WATER_LEVEL'); + +-- CreateEnum +CREATE TYPE "public"."DataSource" AS ENUM ('DHM', 'GLOFAS', 'MANUAL', 'DAILY_MONITORING', 'GFH'); + +-- DropForeignKey +ALTER TABLE "tbl_activities" DROP CONSTRAINT "tbl_activities_categoryId_fkey"; + +-- DropForeignKey +ALTER TABLE "tbl_activities" DROP CONSTRAINT "tbl_activities_managerId_fkey"; + +-- DropForeignKey +ALTER TABLE "tbl_activities" DROP CONSTRAINT "tbl_activities_phaseId_fkey"; + +-- DropForeignKey +ALTER TABLE "tbl_daily_monitoring" DROP CONSTRAINT "tbl_daily_monitoring_sourceId_fkey"; + +-- DropForeignKey +ALTER TABLE "tbl_phases" DROP CONSTRAINT "tbl_phases_riverBasin_fkey"; + +-- DropForeignKey +ALTER TABLE "tbl_sources_data" DROP CONSTRAINT "tbl_sources_data_sourceId_fkey"; + +-- DropForeignKey +ALTER TABLE "tbl_trigger_history" DROP CONSTRAINT "tbl_trigger_history_phaseId_fkey"; + +-- DropForeignKey +ALTER TABLE "tbl_triggers" DROP CONSTRAINT "tbl_triggers_phaseId_fkey"; + +-- AlterTable +ALTER TABLE "mock"."tbl_settings" DROP COLUMN "dataType", +ADD COLUMN "dataType" "mock"."MockSettingDataType" NOT NULL; + +-- DropTable +DROP TABLE "tbl_activities"; + +-- DropTable +DROP TABLE "tbl_activity_categories"; + +-- DropTable +DROP TABLE "tbl_activity_managers"; + +-- DropTable +DROP TABLE "tbl_applications"; + +-- DropTable +DROP TABLE "tbl_daily_monitoring"; + +-- DropTable +DROP TABLE "tbl_phases"; + +-- DropTable +DROP TABLE "tbl_sources"; + +-- DropTable +DROP TABLE "tbl_sources_data"; + +-- DropTable +DROP TABLE "tbl_stats"; + +-- DropTable +DROP TABLE "tbl_trigger_history"; + +-- DropTable +DROP TABLE "tbl_triggers"; + +-- DropEnum +DROP TYPE "ActivityStatus"; + +-- DropEnum +DROP TYPE "ApplicationEnvironment"; + +-- DropEnum +DROP TYPE "DataSource"; + +-- DropEnum +DROP TYPE "Phases"; + +-- DropEnum +DROP TYPE "SettingDataType"; + +-- DropEnum +DROP TYPE "SourceType"; + +-- CreateTable +CREATE TABLE "public"."tbl_activity_categories" ( + "id" SERIAL NOT NULL, + "uuid" TEXT NOT NULL, + "app" TEXT NOT NULL, + "name" TEXT NOT NULL, + "isDeleted" BOOLEAN NOT NULL DEFAULT false, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3), + + CONSTRAINT "tbl_activity_categories_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "public"."tbl_activity_managers" ( + "id" TEXT NOT NULL, + "name" TEXT NOT NULL, + "email" TEXT NOT NULL, + "phone" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) +); + +-- CreateTable +CREATE TABLE "public"."tbl_activities" ( + "id" SERIAL NOT NULL, + "uuid" TEXT NOT NULL, + "app" TEXT NOT NULL, + "title" TEXT NOT NULL, + "leadTime" TEXT NOT NULL, + "phaseId" TEXT NOT NULL, + "categoryId" TEXT NOT NULL, + "managerId" TEXT, + "description" TEXT, + "notes" TEXT, + "status" "public"."ActivityStatus" NOT NULL DEFAULT 'NOT_STARTED', + "activityDocuments" JSONB, + "activityCommunication" JSONB, + "activityPayout" JSONB, + "isAutomated" BOOLEAN NOT NULL DEFAULT false, + "isDeleted" BOOLEAN NOT NULL DEFAULT false, + "completedBy" TEXT, + "completedAt" TIMESTAMP(3), + "differenceInTriggerAndActivityCompletion" TEXT, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3), + + CONSTRAINT "tbl_activities_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "public"."tbl_applications" ( + "cuid" TEXT NOT NULL, + "name" TEXT NOT NULL, + "publicKey" TEXT NOT NULL, + "description" TEXT, + "environment" "public"."ApplicationEnvironment" NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + "updatedBy" TEXT NOT NULL DEFAULT 'system', + "deletedAt" TIMESTAMP(3), + + CONSTRAINT "tbl_applications_pkey" PRIMARY KEY ("cuid") +); + +-- CreateTable +CREATE TABLE "public"."tbl_stats" ( + "name" TEXT NOT NULL, + "data" JSONB NOT NULL, + "group" TEXT, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3), + + CONSTRAINT "tbl_stats_pkey" PRIMARY KEY ("name") +); + +-- CreateTable +CREATE TABLE "public"."tbl_phases" ( + "id" SERIAL NOT NULL, + "uuid" TEXT NOT NULL, + "name" "public"."Phases" NOT NULL, + "activeYear" TEXT NOT NULL, + "requiredMandatoryTriggers" INTEGER DEFAULT 0, + "requiredOptionalTriggers" INTEGER DEFAULT 0, + "receivedMandatoryTriggers" INTEGER DEFAULT 0, + "receivedOptionalTriggers" INTEGER DEFAULT 0, + "canRevert" BOOLEAN NOT NULL DEFAULT false, + "canTriggerPayout" BOOLEAN NOT NULL DEFAULT false, + "isActive" BOOLEAN NOT NULL DEFAULT false, + "riverBasin" TEXT NOT NULL, + "activatedAt" TIMESTAMP(3), + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3), + + CONSTRAINT "tbl_phases_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "public"."tbl_settings" ( + "name" TEXT NOT NULL, + "value" JSONB NOT NULL, + "dataType" "public"."SettingDataType" NOT NULL, + "requiredFields" TEXT[], + "isReadOnly" BOOLEAN NOT NULL DEFAULT false, + "isPrivate" BOOLEAN NOT NULL DEFAULT true, + + CONSTRAINT "tbl_settings_pkey" PRIMARY KEY ("name") +); + +-- CreateTable +CREATE TABLE "public"."tbl_sources" ( + "id" SERIAL NOT NULL, + "uuid" TEXT NOT NULL, + "source" "public"."DataSource"[], + "riverBasin" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3), + + CONSTRAINT "tbl_sources_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "public"."tbl_sources_data" ( + "id" SERIAL NOT NULL, + "type" "public"."SourceType" NOT NULL, + "sourceId" INTEGER NOT NULL, + "dataSource" "public"."DataSource", + "info" JSONB NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3), + + CONSTRAINT "tbl_sources_data_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "public"."tbl_daily_monitoring" ( + "id" SERIAL NOT NULL, + "groupKey" TEXT, + "dataEntryBy" TEXT NOT NULL, + "info" JSONB NOT NULL, + "sourceId" INTEGER NOT NULL, + "dataSource" TEXT, + "isDeleted" BOOLEAN NOT NULL DEFAULT false, + "createdBy" TEXT, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3), + + CONSTRAINT "tbl_daily_monitoring_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "public"."tbl_triggers" ( + "id" SERIAL NOT NULL, + "uuid" TEXT NOT NULL, + "repeatKey" TEXT NOT NULL, + "repeatEvery" TEXT, + "triggerStatement" JSONB, + "triggerDocuments" JSONB, + "notes" TEXT, + "title" TEXT, + "description" TEXT, + "phaseId" TEXT, + "source" "public"."DataSource", + "isMandatory" BOOLEAN NOT NULL DEFAULT false, + "isTriggered" BOOLEAN NOT NULL DEFAULT false, + "isDeleted" BOOLEAN NOT NULL DEFAULT false, + "isDailyMonitored" BOOLEAN NOT NULL DEFAULT false, + "createdBy" TEXT, + "triggeredBy" TEXT, + "transactionHash" TEXT, + "triggeredAt" TIMESTAMP(3), + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3), + + CONSTRAINT "tbl_triggers_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "public"."tbl_trigger_history" ( + "id" SERIAL NOT NULL, + "uuid" TEXT NOT NULL, + "repeatKey" TEXT NOT NULL, + "repeatEvery" TEXT, + "triggerStatement" JSONB, + "triggerDocuments" JSONB, + "notes" TEXT, + "title" TEXT, + "description" TEXT, + "phaseId" TEXT, + "phaseActivationDate" TIMESTAMP(3), + "version" INTEGER NOT NULL, + "source" "public"."DataSource", + "isMandatory" BOOLEAN NOT NULL DEFAULT false, + "isTriggered" BOOLEAN NOT NULL DEFAULT false, + "isDeleted" BOOLEAN NOT NULL DEFAULT false, + "isDailyMonitored" BOOLEAN NOT NULL DEFAULT false, + "triggeredBy" TEXT, + "transactionHash" TEXT, + "triggeredAt" TIMESTAMP(3), + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "createdBy" TEXT, + "updatedAt" TIMESTAMP(3), + "revertedAt" TIMESTAMP(3) NOT NULL, + "revertedBy" TEXT NOT NULL, + + CONSTRAINT "tbl_trigger_history_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "tbl_activity_categories_uuid_key" ON "public"."tbl_activity_categories"("uuid"); + +-- CreateIndex +CREATE UNIQUE INDEX "tbl_activity_categories_app_name_key" ON "public"."tbl_activity_categories"("app", "name"); + +-- CreateIndex +CREATE UNIQUE INDEX "tbl_activity_managers_id_key" ON "public"."tbl_activity_managers"("id"); + +-- CreateIndex +CREATE UNIQUE INDEX "tbl_activities_uuid_key" ON "public"."tbl_activities"("uuid"); + +-- CreateIndex +CREATE UNIQUE INDEX "tbl_stats_name_key" ON "public"."tbl_stats"("name"); + +-- CreateIndex +CREATE UNIQUE INDEX "tbl_phases_uuid_key" ON "public"."tbl_phases"("uuid"); + +-- CreateIndex +CREATE UNIQUE INDEX "tbl_phases_riverBasin_activeYear_name_key" ON "public"."tbl_phases"("riverBasin", "activeYear", "name"); + +-- CreateIndex +CREATE UNIQUE INDEX "tbl_settings_name_key" ON "public"."tbl_settings"("name"); + +-- CreateIndex +CREATE UNIQUE INDEX "tbl_sources_uuid_key" ON "public"."tbl_sources"("uuid"); + +-- CreateIndex +CREATE UNIQUE INDEX "tbl_sources_riverBasin_key" ON "public"."tbl_sources"("riverBasin"); + +-- CreateIndex +CREATE UNIQUE INDEX "tbl_triggers_uuid_key" ON "public"."tbl_triggers"("uuid"); + +-- CreateIndex +CREATE UNIQUE INDEX "tbl_triggers_repeatKey_key" ON "public"."tbl_triggers"("repeatKey"); + +-- AddForeignKey +ALTER TABLE "public"."tbl_activities" ADD CONSTRAINT "tbl_activities_phaseId_fkey" FOREIGN KEY ("phaseId") REFERENCES "public"."tbl_phases"("uuid") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."tbl_activities" ADD CONSTRAINT "tbl_activities_categoryId_fkey" FOREIGN KEY ("categoryId") REFERENCES "public"."tbl_activity_categories"("uuid") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."tbl_activities" ADD CONSTRAINT "tbl_activities_managerId_fkey" FOREIGN KEY ("managerId") REFERENCES "public"."tbl_activity_managers"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."tbl_phases" ADD CONSTRAINT "tbl_phases_riverBasin_fkey" FOREIGN KEY ("riverBasin") REFERENCES "public"."tbl_sources"("riverBasin") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."tbl_sources_data" ADD CONSTRAINT "tbl_sources_data_sourceId_fkey" FOREIGN KEY ("sourceId") REFERENCES "public"."tbl_sources"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."tbl_daily_monitoring" ADD CONSTRAINT "tbl_daily_monitoring_sourceId_fkey" FOREIGN KEY ("sourceId") REFERENCES "public"."tbl_sources"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."tbl_triggers" ADD CONSTRAINT "tbl_triggers_phaseId_fkey" FOREIGN KEY ("phaseId") REFERENCES "public"."tbl_phases"("uuid") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."tbl_trigger_history" ADD CONSTRAINT "tbl_trigger_history_phaseId_fkey" FOREIGN KEY ("phaseId") REFERENCES "public"."tbl_phases"("uuid") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/packages/database/prisma/schema/mock.prisma b/packages/database/prisma/schema/mock.prisma index aa13f1d..7e377d9 100644 --- a/packages/database/prisma/schema/mock.prisma +++ b/packages/database/prisma/schema/mock.prisma @@ -10,7 +10,7 @@ enum MockSettingDataType { model MockSetting { name String @id @unique value Json - dataType SettingDataType + dataType MockSettingDataType requiredFields String[] isReadOnly Boolean @default(false) isPrivate Boolean @default(true) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 71a982b..43431ac 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -179,6 +179,88 @@ importers: specifier: ^4.2.0 version: 4.2.0 + apps/mock-api: + dependencies: + '@lib/core': + specifier: workspace:* + version: link:../../packages/core + '@lib/database': + specifier: workspace:* + version: link:../../packages/database + '@lib/dhm-adapter': + specifier: workspace:* + version: link:../../packages/dhm-adapter + '@lib/glofas-adapter': + specifier: workspace:* + version: link:../../packages/glofas-adapter + '@nestjs/platform-express': + specifier: ^10.3.7 + version: 10.4.20(@nestjs/common@10.4.20)(@nestjs/core@10.4.20) + cheerio: + specifier: ^1.1.2 + version: 1.1.2 + expr-eval: + specifier: ^2.0.2 + version: 2.0.2 + luxon: + specifier: ^3.7.2 + version: 3.7.2 + reflect-metadata: + specifier: ^0.1.13 + version: 0.1.14 + rxjs: + specifier: ^7.8.1 + version: 7.8.2 + devDependencies: + '@nestjs/cli': + specifier: ^10.0.0 + version: 10.4.9(@swc/cli@0.6.0)(@swc/core@1.15.1) + '@nestjs/schematics': + specifier: ^10.0.0 + version: 10.2.3(typescript@5.9.2) + '@nestjs/testing': + specifier: ^10.0.1 + version: 10.4.20(@nestjs/common@10.4.20)(@nestjs/core@10.4.20)(@nestjs/microservices@10.4.20)(@nestjs/platform-express@10.4.20) + '@swc/cli': + specifier: ^0.6.0 + version: 0.6.0(@swc/core@1.15.1) + '@swc/core': + specifier: ^1.10.7 + version: 1.15.1 + '@types/express': + specifier: ^4.17.17 + version: 4.17.25 + '@types/jest': + specifier: ^29.5.14 + version: 29.5.14 + '@types/node': + specifier: ^20.3.1 + version: 20.19.25 + '@types/supertest': + specifier: ^6.0.2 + version: 6.0.3 + '@workspace/eslint-config': + specifier: workspace:* + version: link:../../packages/eslint-config + '@workspace/typescript-config': + specifier: workspace:* + version: link:../../packages/typescript-config + jest: + specifier: ^29.7.0 + version: 29.7.0(@types/node@20.19.25)(ts-node@10.9.2) + source-map-support: + specifier: ^0.5.21 + version: 0.5.21 + supertest: + specifier: ^7.0.0 + version: 7.1.4 + ts-jest: + specifier: ^29.2.5 + version: 29.4.5(@babel/core@7.28.5)(jest@29.7.0)(typescript@5.9.2) + tsconfig-paths: + specifier: ^4.2.0 + version: 4.2.0 + apps/triggers: dependencies: '@lib/core': @@ -1291,7 +1373,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.19.25 + '@types/node': 22.19.1 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 @@ -1357,14 +1439,14 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.19.25 + '@types/node': 22.19.1 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.19.25)(ts-node@10.9.2) + jest-config: 29.7.0(@types/node@22.19.1)(ts-node@10.9.2) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -1402,7 +1484,7 @@ packages: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.19.25 + '@types/node': 22.19.1 jest-mock: 29.7.0 dev: true @@ -1441,7 +1523,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.19.25 + '@types/node': 22.19.1 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -1521,7 +1603,7 @@ packages: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.31 - '@types/node': 20.19.25 + '@types/node': 22.19.1 chalk: 4.1.2 collect-v8-coverage: 1.0.3 exit: 0.1.2 @@ -1674,7 +1756,7 @@ packages: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 20.19.25 + '@types/node': 22.19.1 '@types/yargs': 17.0.34 chalk: 4.1.2 dev: true @@ -2913,13 +2995,13 @@ packages: resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} dependencies: '@types/connect': 3.4.38 - '@types/node': 20.19.25 + '@types/node': 22.19.1 dev: true /@types/connect@3.4.38: resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} dependencies: - '@types/node': 20.19.25 + '@types/node': 22.19.1 dev: true /@types/cookiejar@2.1.5: @@ -2947,7 +3029,7 @@ packages: /@types/express-serve-static-core@4.19.7: resolution: {integrity: sha512-FvPtiIf1LfhzsaIXhv/PHan/2FeQBbtBDtfX2QfvPxdUelMDEckK08SM6nqo1MIZY3RUlfA+HV8+hFUSio78qg==} dependencies: - '@types/node': 20.19.25 + '@types/node': 22.19.1 '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 '@types/send': 1.2.1 @@ -3049,20 +3131,20 @@ packages: resolution: {integrity: sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==} dependencies: '@types/mime': 1.3.5 - '@types/node': 20.19.25 + '@types/node': 22.19.1 dev: true /@types/send@1.2.1: resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==} dependencies: - '@types/node': 20.19.25 + '@types/node': 22.19.1 dev: true /@types/serve-static@1.15.10: resolution: {integrity: sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==} dependencies: '@types/http-errors': 2.0.5 - '@types/node': 20.19.25 + '@types/node': 22.19.1 '@types/send': 0.17.6 dev: true @@ -3075,7 +3157,7 @@ packages: dependencies: '@types/cookiejar': 2.1.5 '@types/methods': 1.1.4 - '@types/node': 20.19.25 + '@types/node': 22.19.1 form-data: 4.0.4 dev: true @@ -6829,7 +6911,7 @@ packages: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.19.25 + '@types/node': 22.19.1 chalk: 4.1.2 co: 4.6.0 dedent: 1.7.0 @@ -6990,6 +7072,47 @@ packages: - supports-color dev: true + /jest-config@29.7.0(@types/node@22.19.1)(ts-node@10.9.2): + resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + dependencies: + '@babel/core': 7.28.5 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.19.1 + babel-jest: 29.7.0(@babel/core@7.28.5) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + ts-node: 10.9.2(@types/node@22.19.1)(typescript@5.9.2) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + dev: true + /jest-diff@27.5.1: resolution: {integrity: sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -7083,7 +7206,7 @@ packages: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.19.25 + '@types/node': 22.19.1 jest-mock: 29.7.0 jest-util: 29.7.0 dev: true @@ -7124,7 +7247,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.9 - '@types/node': 20.19.25 + '@types/node': 22.19.1 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -7241,7 +7364,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.19.25 + '@types/node': 22.19.1 jest-util: 29.7.0 dev: true @@ -7372,7 +7495,7 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.19.25 + '@types/node': 22.19.1 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -7433,7 +7556,7 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.19.25 + '@types/node': 22.19.1 chalk: 4.1.2 cjs-module-lexer: 1.4.3 collect-v8-coverage: 1.0.3 @@ -7535,7 +7658,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.19.25 + '@types/node': 22.19.1 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -7585,7 +7708,7 @@ packages: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.19.25 + '@types/node': 22.19.1 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -7606,7 +7729,7 @@ packages: resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 20.19.25 + '@types/node': 22.19.1 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 From fcf13013c9a57924e7a7061b05f331027f5f4dc3 Mon Sep 17 00:00:00 2001 From: Pratiksharai-Rumsan Date: Wed, 3 Dec 2025 15:09:55 +0545 Subject: [PATCH 2/3] update readme file --- apps/mock-api/Dockerfile | 49 ---- apps/mock-api/README.md | 194 ++++++++++--- apps/mock-api/package.json | 2 - apps/mock-api/src/app.module.ts | 5 +- apps/mock-api/src/common/index.ts | 270 ------------------ apps/mock-api/src/constants/datasourceUrls.ts | 18 -- .../mock-api/src/forecast/forecast.service.ts | 2 +- apps/mock-api/src/triggers/dto/trigger.dto.ts | 34 --- apps/mock-api/src/triggers/trigger.module.ts | 10 - apps/mock-api/src/triggers/trigger.service.ts | 87 ------ .../src/triggers/triggers.controller.ts | 52 ---- apps/mock-api/src/types/data-source.ts | 214 -------------- pnpm-lock.yaml | 6 - 13 files changed, 159 insertions(+), 784 deletions(-) delete mode 100644 apps/mock-api/Dockerfile delete mode 100644 apps/mock-api/src/common/index.ts delete mode 100644 apps/mock-api/src/constants/datasourceUrls.ts delete mode 100644 apps/mock-api/src/triggers/dto/trigger.dto.ts delete mode 100644 apps/mock-api/src/triggers/trigger.module.ts delete mode 100644 apps/mock-api/src/triggers/trigger.service.ts delete mode 100644 apps/mock-api/src/triggers/triggers.controller.ts diff --git a/apps/mock-api/Dockerfile b/apps/mock-api/Dockerfile deleted file mode 100644 index 5bf512d..0000000 --- a/apps/mock-api/Dockerfile +++ /dev/null @@ -1,49 +0,0 @@ -FROM node:20-alpine AS base - -# The web Dockerfile is copy-pasted into our main docs at /docs/handbook/deploying-with-docker. -# Make sure you update this Dockerfile, the Dockerfile in the web workspace and copy that over to Dockerfile in the docs. - -FROM base AS builder -# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. -RUN apk update -RUN apk add --no-cache libc6-compat openssl -# Set working directory -WORKDIR /app -RUN npm install -g turbo -COPY . . -RUN turbo prune api --docker - -# Add lockfile and package.json's of isolated subworkspace -FROM base AS installer -RUN apk update -RUN apk add --no-cache libc6-compat openssl -RUN npm install -g pnpm@8.14.1 -WORKDIR /app - - -# First install dependencies (as they change less often) -COPY --from=builder /app/out/json/ . -RUN pnpm install -COPY --from=builder /app/out/full/ . -RUN pnpm turbo build - -# Clean up unnecessary files to reduce image size -RUN rm -rf node_modules -RUN find apps/api -type f -not -path 'apps/api/dist/*' -not -name 'package.json' -delete && rm -rf apps/api/test apps/api/src -RUN pnpm install --prod && pnpm store prune - - -FROM base AS runner -WORKDIR /app - -# Create log directory and set permissions -RUN mkdir -p /app/.log && chmod -R 777 /app/.log -# Don't run production as root -RUN addgroup --system --gid 1001 nestjs -RUN adduser --system --uid 1001 nestjs -USER nestjs -COPY --from=installer /app . -# Tag the final image -LABEL stage="final" -RUN docker rmi $(docker images -f "label=stage=intermediate" -q) || true -CMD node apps/api/dist/main.js diff --git a/apps/mock-api/README.md b/apps/mock-api/README.md index 59f467f..addbbb3 100644 --- a/apps/mock-api/README.md +++ b/apps/mock-api/README.md @@ -1,65 +1,185 @@ -# NestJs API Seed +# Mock API - GLOFAS & GFH Data Simulator -The application is NestJS API Seed. This application provides RESTful APIs for managing operations and integrates with the shared database package for data persistence. +A NestJS-based mock API server that simulates external data sources (GLOFAS, GFH, DHM) for testing and development purposes. This mock server eliminates the need to call real external APIs during development and testing, providing fast, reliable, and predictable responses. -## Overview +## 🎯 Overview -The API application is built with NestJS and provides a robust API layer for handling various trigger operations. It includes comprehensive error handling, logging, API documentation, and database integration through the shared database package. +The Mock API is built with NestJS and provides mock endpoints that replicate the behavior of external flood forecasting systems. It uses the `mock` database schema to store and serve test data, allowing developers to test trigger systems without depending on external API availability, rate limits, or network connectivity. -## Features +## 🚀 Purpose -- **RESTful API**: Well-structured REST endpoints for trigger operations -- **Database Integration**: Uses the shared `@lib/database` package for data operations -- **Exception Handling**: Global exception filters for database and application errors -- **API Documentation**: Auto-generated Swagger documentation -- **Logging**: Structured logging with Winston integration -- **Validation**: Request validation using class-validator -- **CORS Support**: Cross-origin resource sharing enabled -- **Development Tools**: Hot reload and debugging support +**Why Mock API?** -## Project Structure +Instead of calling real external APIs during development/testing: -``` +- ❌ **Real APIs**: Slow, rate-limited, require authentication, unstable +- ✅ **Mock API**: Fast, unlimited calls, no auth needed, always available + +This mock server enables: + +- 🧪 **Isolated Testing**: Test without external dependencies +- ⚡ **Fast Development**: No network latency or API delays +- 🎭 **Scenario Simulation**: Test edge cases (high floods, API failures, etc.) +- 💰 **Cost Savings**: No API usage costs or rate limit concerns +- 🔒 **Offline Development**: Work without internet connection + +## ✨ Features + +- **Mock Forecast Endpoints**: Simulates GLOFAS and GFH flood forecast APIs +- **Mock Trigger Management**: CRUD operations for testing trigger workflows +- **Database Integration**: Uses `@lib/database` with `mock` schema +- **Swagger Documentation**: Interactive API documentation at `/swagger` +- **Winston Logging**: Structured logging for debugging +- **CORS Enabled**: Cross-origin requests supported +- **Global Validation**: Request data validation with class-validator +- **Exception Handling**: Comprehensive error handling filters + +## 📁 Project Structure + +```text src/ -├── app.controller.ts # Main application controller -├── app.module.ts # Root application module -├── app.service.ts # Main application service -├── main.ts # Application bootstrap file -├── all-exceptions.filter.ts # Global exception filter +├── app.controller.ts # Main application controller +├── app.module.ts # Root module with database & HTTP setup +├── app.service.ts # Application service +├── main.ts # Bootstrap file (port: 3005) +├── all-exceptions.filter.ts # Global exception handler ├── helpers/ -│ └── winston.logger.ts # Winston logger configuration -└── source-data/ - ├── source-data.controller.ts # Source data API endpoints - ├── source-data.module.ts # Source data module - └── source-data.service.ts # Source data business logic +│ └── winston.logger.ts # Winston logger configuration +├── forecast/ +│ ├── forecast.controller.ts # Mock forecast endpoints (GLOFAS, GFH) +│ ├── forecast.service.ts # Forecast data service +│ └── forecast.module.ts # Forecast module +├── triggers/ +│ ├── triggers.controller.ts # Mock trigger CRUD endpoints +│ ├── trigger.service.ts # Trigger business logic +│ ├── trigger.module.ts # Triggers module +│ └── dto/ +│ └── trigger.dto.ts # Trigger data transfer objects +├── constants/ # Application constants +├── types/ # TypeScript type definitions +└── utils/ # Utility functions ``` -## Environment Configuration +## 🔌 API Endpoints + +### Forecast Endpoints (Mock External APIs) + +| Method | Endpoint | Description | Mocks | +| ------ | ----------------------------------------- | ------------------------- | ---------------- | +| `GET` | `/v1/forecast/river` | Get river forecast data | DHM River Watch | +| `GET` | `/v1/forecast/glofas` | Get GLOFAS forecast data | GLOFAS WMS API | +| `POST` | `/v1/forecast/gauges:searchGaugesByArea` | Search GFH gauges by area | Google Flood Hub | +| `GET` | `/v1/forecast/gaugeModels:batchGet` | Get GFH gauge metadata | Google Flood Hub | +| `GET` | `/v1/forecast/gauges:queryGaugeForecasts` | Get GFH gauge forecasts | Google Flood Hub | + +### Trigger Management Endpoints (Testing) + +| Method | Endpoint | Description | +| -------- | ------------------ | ------------------ | +| `GET` | `/v1/triggers` | Get all triggers | +| `GET` | `/v1/triggers/:id` | Get trigger by ID | +| `POST` | `/v1/triggers` | Create new trigger | +| `PATCH` | `/v1/triggers/:id` | Update trigger | +| `DELETE` | `/v1/triggers/:id` | Delete trigger | + +### Health Check -The application requires environment variables to be configured. Copy the example file and update the values: +| Method | Endpoint | Description | +| ------ | -------- | ------------------ | +| `GET` | `/v1` | Basic health check | + +## 🛠️ Environment Configuration + +Copy the environment example file and update the values: ```bash cp .env.example .env ``` -The application supports both direct DATABASE_URL configuration and individual database parameters. See the `.env.example` file for all available configuration options. +Update the `.env` file: + +```bash +# Database Configuration (uses mock schema) +DB_HOST=localhost +DB_PORT=5432 +DB_USER=postgres +DB_PASSWORD=postgres +DB_NAME=rahat_triggers + +# Application Configuration +PORT=3005 +NODE_ENV=development + +# Optional: Direct DATABASE_URL +# DATABASE_URL=postgresql://postgres:postgres@localhost:5432/rahat_triggers?schema=mock +``` + +**Note:** The mock API uses the same database as the triggers app but operates in the `mock` schema for data isolation. -## Available Scripts +## 📦 Installation & Setup -### Development +### 1. Install Dependencies + +From the monorepo root: ```bash -# Start in development mode with hot reload -pnpm dev +pnpm install +``` -# Start in debug mode -pnpm start:debug +### 2. Setup Database + +Generate Prisma client and run migrations: -# Build the application +```bash +# Generate Prisma client +pnpm --filter @lib/database db:generate + +# Run migrations +pnpm --filter @lib/database db:migrate + +# Optional: Seed mock data +pnpm --filter @lib/database seed +``` + +### 3. Build the Package + +```bash +# Build mock-api +pnpm --filter mock-api build + +# Or build all packages pnpm build +``` + +## 🚀 Running the Application + +### Development Mode + +```bash +# From monorepo root +pnpm --filter mock-api dev -# Start in production mode -pnpm start:prod +# Or from app directory +cd apps/mock-api +pnpm dev +``` + +The server will start at: **`http://localhost:3005`** + +### Production Mode + +```bash +# Build first +pnpm --filter mock-api build + +# Start production server +pnpm --filter mock-api start:prod +``` + +### Debug Mode + +```bash +pnpm --filter mock-api dev:debug ``` ### Testing diff --git a/apps/mock-api/package.json b/apps/mock-api/package.json index 7f4808c..7275868 100644 --- a/apps/mock-api/package.json +++ b/apps/mock-api/package.json @@ -25,8 +25,6 @@ "dependencies": { "@lib/core": "workspace:*", "@lib/database": "workspace:*", - "@lib/dhm-adapter": "workspace:*", - "@lib/glofas-adapter": "workspace:*", "@nestjs/platform-express": "^10.3.7", "cheerio": "^1.1.2", "expr-eval": "^2.0.2", diff --git a/apps/mock-api/src/app.module.ts b/apps/mock-api/src/app.module.ts index fd63038..1ca5614 100644 --- a/apps/mock-api/src/app.module.ts +++ b/apps/mock-api/src/app.module.ts @@ -2,12 +2,10 @@ import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { PrismaModule } from '@lib/database'; -// import { DhmModule } from '@lib/dhm-adapter'; + import { ConfigModule } from '@nestjs/config'; import { HttpModule } from '@nestjs/axios'; import { SettingsModule } from '@lib/core'; -// import { GlofasModule } from '@lib/glofas-adapter'; -import { TriggersModule } from './triggers/trigger.module'; @Module({ imports: [ @@ -21,7 +19,6 @@ import { TriggersModule } from './triggers/trigger.module'; global: true, }), - TriggersModule, SettingsModule, ], controllers: [AppController], diff --git a/apps/mock-api/src/common/index.ts b/apps/mock-api/src/common/index.ts deleted file mode 100644 index b6beca7..0000000 --- a/apps/mock-api/src/common/index.ts +++ /dev/null @@ -1,270 +0,0 @@ -import * as cheerio from 'cheerio'; -export const getFormattedDate = (date: Date = new Date()) => { - // const date = new Date(); - // date.setDate(date.getDate() - 1); // Set date to previous day - const year = date.getFullYear(); - const month = String(date.getMonth() + 1).padStart(2, '0'); // getMonth() returns 0-based month, hence add 1 - const day = String(date.getDate()).padStart(2, '0'); - - const dateTimeString = `${year}-${month}-${day}T00:00:00`; - const dateString = `${year}-${month}-${day}`; - - return { dateString, dateTimeString }; -}; -export function parseGlofasData(content: string) { - const $ = cheerio.load(content); - - // 2 yr return period table - const rpTable2yr = $( - 'table[class="table-forecast-result table-forecast-result-global"][summary="ECMWF-ENS > 2 yr RP"]', - ); - - // 5 yr return period table - const rpTable5yr = $( - 'table[class="table-forecast-result table-forecast-result-global"][summary="ECMWF-ENS > 5 yr RP"]', - ); - - // 20 yr return period table - const rpTable20yr = $( - 'table[class="table-forecast-result table-forecast-result-global"][summary="ECMWF-ENS > 20 yr RP"]', - ); - - // point forecast table - const pfTable = $('table.tbl_info_point[summary="Point Forecast"]'); - - const hydrographElement = $('.forecast_images').find( - 'img[alt="Discharge Hydrograph (ECMWF-ENS)"]', - ); - - if ( - rpTable2yr.length === 0 || - rpTable5yr.length === 0 || - rpTable20yr.length === 0 || - pfTable.length === 0 || - hydrographElement.length === 0 - ) { - return; - } - - const returnPeriodTable2yr = parseReturnPeriodTable(rpTable2yr, $); - const returnPeriodTable5yr = parseReturnPeriodTable(rpTable5yr, $); - const returnPeriodTable20yr = parseReturnPeriodTable(rpTable20yr, $); - const pointForecastData = parsePointForecast(pfTable, $); - const hydrographImageUrl = hydrographElement.attr('src'); - return { - returnPeriodTable2yr, - returnPeriodTable5yr, - returnPeriodTable20yr, - pointForecastData, - hydrographImageUrl, - }; -} -function parseReturnPeriodTable( - rpTable: cheerio.Cheerio, - $: cheerio.CheerioAPI, -) { - // first header row, consists of column names - const headerRow = rpTable.find('tr').first(); - // get column names (th elements in tr) - const returnPeriodHeaders = headerRow - .find('th') - .map((_, element) => $(element).text().trim()) - .toArray(); - - // first 10 data row (excluding the header) , data from latest day - const dataRow = rpTable.find('tr').slice(1, 11); - const returnPeriodData = []; - - for (const row of dataRow) { - const dataValues = $(row) - .find('td') - .map((_, element) => $(element).text().trim()) - .toArray(); - - returnPeriodData.push(dataValues); - } - - return { returnPeriodData, returnPeriodHeaders }; -} - -function parsePointForecast( - pfTable: cheerio.Cheerio, - $: cheerio.CheerioAPI, -) { - const headerRow = pfTable.find('tr').first(); - const columnNames = headerRow - .find('th') - .map((i, element) => $(element).text().trim()) - .toArray(); - - const dataRow = pfTable.find('tr').eq(1); - - const forecastDate = dataRow.find('td:nth-child(1)').text().trim(); // Using nth-child selector - const maxProbability = dataRow.find('td:nth-child(2)').text().trim(); - const alertLevel = dataRow.find('td:nth-child(3)').text().trim(); - const maxProbabilityStep = dataRow.find('td:nth-child(4)').text().trim(); - const dischargeTendencyImage = dataRow - .find('td:nth-child(5) img') - .attr('src'); // Extract image src - const peakForecasted = dataRow.find('td:nth-child(6)').text().trim(); - - return { - forecastDate: { - header: columnNames[0], - data: forecastDate, - }, - maxProbability: { - header: columnNames[1], - data: maxProbability, - }, - alertLevel: { - header: columnNames[2], - data: alertLevel, - }, - maxProbabilityStep: { - header: columnNames[3], - data: maxProbabilityStep, - }, - dischargeTendencyImage: { - header: columnNames[4], - data: dischargeTendencyImage, - }, - peakForecasted: { - header: columnNames[5], - data: peakForecasted, - }, - }; -} - -export const getTriggerAndActivityCompletionTimeDifference = ( - start: Date, - end: Date, -) => { - const trigger = new Date(start); - const completion = new Date(end); - - const isCompletedEarlier = completion < trigger; - - const msDifference = completion.getTime() - trigger.getTime(); - const absoluteMsDifference = Math.abs(msDifference); - - let differenceInSeconds = Math.floor(absoluteMsDifference / 1000); - - const days = Math.floor(differenceInSeconds / (24 * 3600)); - differenceInSeconds %= 24 * 3600; - - const hours = Math.floor(differenceInSeconds / 3600); - differenceInSeconds %= 3600; - - const minutes = Math.floor(differenceInSeconds / 60); - const seconds = differenceInSeconds % 60; - - const parts = [ - days ? `${days} day${days !== 1 ? 's' : ''}` : '', - hours ? `${hours} hour${hours !== 1 ? 's' : ''}` : '', - minutes ? `${minutes} minute${minutes !== 1 ? 's' : ''}` : '', - seconds ? `${seconds} second${seconds !== 1 ? 's' : ''}` : '', - ]; - - const result = parts.filter(Boolean).join(' '); - - return isCompletedEarlier ? `-${result}` : result; -}; - -export function buildQueryParams(seriesId: number, from = null, to = null) { - const currentDate = new Date().toISOString().split('T')[0]; - const endOfFrom = from ? new Date(from.setHours(23, 59, 59, 999)) : null; - - from = endOfFrom ? endOfFrom.toISOString().split('T')[0] : null; - to = to ? new Date(to).toISOString().split('T')[0] : null; - - return { - series_id: seriesId, - date_from: from || currentDate, - date_to: to || currentDate, - }; -} - -export function scrapeDataFromHtml(html: string): { [key: string]: any }[] { - if (!html?.trim()) return []; - - const results: { [key: string]: any }[] = []; - - // Pre-compiled regex patterns for better performance - const headerRegex = /]*>(.*?)<\/th>/gs; - const htmlTagRegex = /<[^>]*>/g; - const whitespaceRegex = /\s+/g; - - // Extract headers first - const headers: string[] = []; - let headerMatch: RegExpExecArray | null; - - while ((headerMatch = headerRegex.exec(html)) !== null) { - const headerText = headerMatch[1] - .replace(htmlTagRegex, '') - .replace(whitespaceRegex, ' ') - .trim(); - - if (headerText) { - headers.push(headerText); - } - } - - // If no headers found, return empty array - if (headers.length === 0) return []; - - // Create dynamic regex pattern based on number of headers - const cellPattern = ']*>(.*?)\\s*'; - const tableRowRegex = new RegExp( - `]*>\\s*${cellPattern.repeat(headers.length)}`, - 'gs', - ); - - let match: RegExpExecArray | null; - - while ((match = tableRowRegex.exec(html)) !== null) { - const rowData: { [key: string]: any } = {}; - let hasValidData = false; - - // Process each cell according to its header - for (let i = 0; i < headers.length; i++) { - const cellRaw = match[i + 1] - ?.replace(htmlTagRegex, '') - .replace(whitespaceRegex, ' ') - .trim(); - - if (!cellRaw) continue; - - const header = headers[i]; - const headerLower = header.toLowerCase(); - - // Handle different data types based on header name - if (headerLower.includes('date') || headerLower.includes('time')) { - // Handle date/time columns - const date = new Date(cellRaw); - if (!isNaN(date.getTime())) { - rowData[header] = date.toISOString(); - hasValidData = true; - } - } else { - // Try to parse as number first - const numericValue = parseFloat(cellRaw); - if (!isNaN(numericValue)) { - rowData[header] = numericValue; - hasValidData = true; - } else { - // Keep as string if not numeric - rowData[header] = cellRaw; - hasValidData = true; - } - } - } - - // Only add row if we have at least one valid data point - if (hasValidData && Object.keys(rowData).length > 0) { - results.push(rowData); - } - } - - return results; -} diff --git a/apps/mock-api/src/constants/datasourceUrls.ts b/apps/mock-api/src/constants/datasourceUrls.ts deleted file mode 100644 index 1670a64..0000000 --- a/apps/mock-api/src/constants/datasourceUrls.ts +++ /dev/null @@ -1,18 +0,0 @@ -export const hydrologyObservationUrl = - 'https://hydrology.gov.np/gss/api/observation'; - -export const riverStationUrl = - 'https://www.dhm.gov.np/frontend_dhm/site/getRiverWatchFilter'; - -export const rainfallStationUrl = - 'https://www.dhm.gov.np/frontend_dhm/hydrology/getRainfallFilter'; - -export const dhmRiverWatchUrl = - 'https://dhm.gov.np/site/getRiverWatchBySeriesId_Single'; - -export const dhmRainfallWatchUrl = - 'http://www.dhm.gov.np/frontend_dhm/hydrology/getRainfallWatchMapBySeriesId'; - -export const gfhUrl = 'https://floodforecasting.googleapis.com/v1'; - -export const glofasUrl = 'https://ows.globalfloods.eu/glofas-ows/ows.py'; diff --git a/apps/mock-api/src/forecast/forecast.service.ts b/apps/mock-api/src/forecast/forecast.service.ts index 8b61a3d..2d240d5 100644 --- a/apps/mock-api/src/forecast/forecast.service.ts +++ b/apps/mock-api/src/forecast/forecast.service.ts @@ -1,7 +1,7 @@ import { Injectable, Logger, HttpException, HttpStatus } from '@nestjs/common'; import { demoRiverForecast } from 'src/data/dhm'; import { PrismaService } from '@lib/database'; -import { glofasRawResponseTemplate } from 'src/data/glofas/raw-response'; +import { glofasRawResponseTemplate } from '../data/glofas/raw-response'; import { DataSourceSettings } from '../types/data-source'; import { parseDate } from '../utils/date'; import { diff --git a/apps/mock-api/src/triggers/dto/trigger.dto.ts b/apps/mock-api/src/triggers/dto/trigger.dto.ts deleted file mode 100644 index b536149..0000000 --- a/apps/mock-api/src/triggers/dto/trigger.dto.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { IsString, IsJSON, IsOptional, IsBoolean } from 'class-validator'; - -export class TriggerDto { - @IsString() - repeatKey: string; - - @IsString() - repeatEvery: string; - - @IsJSON() - triggerStatement: any; - - @IsString() - @IsOptional() - triggerDocuments?: any; - - @IsString() - notes: string; - - @IsString() - title: string; - - @IsString() - description: string; - - @IsBoolean() - isMandatory: boolean; - - @IsBoolean() - isTriggered: boolean; - - @IsBoolean() - isDeleted: boolean; -} diff --git a/apps/mock-api/src/triggers/trigger.module.ts b/apps/mock-api/src/triggers/trigger.module.ts deleted file mode 100644 index 3718c47..0000000 --- a/apps/mock-api/src/triggers/trigger.module.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Module } from '@nestjs/common'; -import { TriggersController } from './triggers.controller'; -import { TriggersService } from './trigger.service'; - -@Module({ - imports: [], - controllers: [TriggersController], - providers: [TriggersService], -}) -export class TriggersModule {} diff --git a/apps/mock-api/src/triggers/trigger.service.ts b/apps/mock-api/src/triggers/trigger.service.ts deleted file mode 100644 index ce4137e..0000000 --- a/apps/mock-api/src/triggers/trigger.service.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { Prisma, PrismaService } from '@lib/database'; -import { Injectable, Logger } from '@nestjs/common'; -import { TriggerDto } from './dto/trigger.dto'; -import { Parser } from 'expr-eval'; - -@Injectable() -export class TriggersService { - private readonly logger = new Logger(TriggersService.name); - constructor(private readonly prismaService: PrismaService) {} - - async findAll() { - this.logger.log('Finding all triggers'); - return this.prismaService.trigger.findMany(); - } - - async findOne(id: number) { - this.logger.log(`Finding trigger with id: ${id}`); - return this.prismaService.trigger.findUnique({ - where: { id }, - }); - } - - async create(data: TriggerDto) { - // Payload example - /* - { - "repeatKey": "asfadf", - "repeatEvery": "1", - "triggerStatement": { - "phase": "Readness", - "value": 5, - "source": "water_level_m", - "operator": ">=", - "expression": "warning_level >= 5", - "riverBasin": "Doda", - "sourceSubType": "warning_level" - }, - "triggerDocuments": null, - "notes": "asdfasdfasf", - "title": "Titile", - "description": "this is atest", - "phaseId": null, - "source": null, - "isMandatory": false, - "isTriggered": false, - "isDeleted": false, - "isDailyMonitored": false, - "createdBy": null, - "triggeredBy": null, - "transactionHash": null, - "triggeredAt": null, - } - */ - this.logger.log('Creating trigger', data); - const triggerStatement = JSON.parse(data.triggerStatement) as { - expression: string; - source: string; - operator: string; - value: number; - sourceSubType: string; - }; - console.log('Trigger statement', triggerStatement); - - const result = Parser.evaluate(triggerStatement.expression, { - [triggerStatement.sourceSubType]: 90, - }); - - console.log('Result', result); - - return this.prismaService.trigger.create({ - data: { - ...data, - triggerStatement: triggerStatement, - }, - }); - } - - async update(id: number, data: Prisma.TriggerUpdateInput) { - this.logger.log(`Updating trigger with id: ${id}`, data); - return this.prismaService.trigger.update({ where: { id }, data }); - } - - async delete(id: number) { - this.logger.log(`Deleting trigger with id: ${id}`); - return this.prismaService.trigger.delete({ where: { id } }); - } -} diff --git a/apps/mock-api/src/triggers/triggers.controller.ts b/apps/mock-api/src/triggers/triggers.controller.ts deleted file mode 100644 index a4e10a6..0000000 --- a/apps/mock-api/src/triggers/triggers.controller.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { ApiResponse, ApiTags, ApiOperation } from '@nestjs/swagger'; -import { Controller, Param } from '@nestjs/common'; -import { Get, Post, Patch, Delete, Body } from '@nestjs/common'; -import { TriggersService } from './trigger.service'; -import { Prisma } from '@lib/database'; -import { TriggerDto } from './dto/trigger.dto'; - -@ApiTags('triggers') -@Controller('triggers') -export class TriggersController { - constructor(private readonly triggersService: TriggersService) {} - - @Get() - @ApiOperation({ summary: 'Get all triggers' }) - @ApiResponse({ status: 200, description: 'Triggers retrieved successfully' }) - findAll() { - return this.triggersService.findAll(); - } - - @Get(':id') - @ApiOperation({ summary: 'Get a trigger by ID' }) - @ApiResponse({ status: 200, description: 'Trigger retrieved successfully' }) - @ApiResponse({ status: 404, description: 'Trigger not found' }) - findOne(@Param('id') id: number) { - return this.triggersService.findOne(id); - } - - @Post() - @ApiOperation({ summary: 'Create a new trigger' }) - @ApiResponse({ status: 201, description: 'Trigger created successfully' }) - @ApiResponse({ status: 400, description: 'Bad request' }) - create(@Body() data: TriggerDto) { - return this.triggersService.create(data); - } - - @Patch(':id') - @ApiOperation({ summary: 'Update a trigger by ID' }) - @ApiResponse({ status: 200, description: 'Trigger updated successfully' }) - @ApiResponse({ status: 400, description: 'Bad request' }) - @ApiResponse({ status: 404, description: 'Trigger not found' }) - update(@Param('id') id: number, @Body() data: Prisma.TriggerUpdateInput) { - return this.triggersService.update(id, data); - } - - @Delete(':id') - @ApiOperation({ summary: 'Delete a trigger by ID' }) - @ApiResponse({ status: 200, description: 'Trigger deleted successfully' }) - @ApiResponse({ status: 404, description: 'Trigger not found' }) - delete(@Param('id') id: number) { - return this.triggersService.delete(id); - } -} diff --git a/apps/mock-api/src/types/data-source.ts b/apps/mock-api/src/types/data-source.ts index 1c82c8b..da0647d 100644 --- a/apps/mock-api/src/types/data-source.ts +++ b/apps/mock-api/src/types/data-source.ts @@ -1,217 +1,3 @@ -// export interface RiverStationItem { -// name: string; -// id: number; -// stationIndex: string; -// basin: string; -// district: string; -// latitude: number | null; -// longitude: number | null; -// series_id: number; -// waterLevel: number | null; -// status: string; -// warning_level: string; -// danger_level: string; -// steady: string; -// onm: string; -// description: string; -// elevation: number; -// images: Array>; -// tags: string[]; -// } - -// export type RainfallStationItem = { -// id: number; -// series_id: number; -// stationIndex: string; -// name: string; -// status: string; -// basin: string; -// district: string; -// description: string; -// longitude: number; -// latitude: number; -// value: number | null; -// interval: number | null; -// blink: boolean; -// }; - -// export interface RiverWaterHistoryItem { -// datetime: string; -// value: number; -// max?: number; -// min?: number; -// } - -// export interface RiverStationData extends RiverStationItem { -// history?: RiverWaterHistoryItem[]; -// } - -// export interface RainfallStationData extends RainfallStationItem { -// history?: RiverWaterHistoryItem[]; -// } - -// export interface gfhStationDetails { -// riverBasin: string; -// source: string; -// latitude: number; -// longitude: number; -// riverGaugeId: string; -// stationName: string; -// warningLevel: string; -// dangerLevel: string; -// extremeDangerLevel: string; -// basinSize: number; -// forecastDate: string; -// } - -// export interface gfhStationData extends gfhStationDetails { -// history?: RiverWaterHistoryItem[]; -// } - -// export enum SourceDataTypeEnum { -// POINT = 1, -// HOURLY = 2, -// DAILY = 3, -// } - -// export type InputItem = -// | { -// Date: string; -// Point: number; -// } -// | { -// Date: string; -// Max: number; -// Min: number; -// Average: number; -// } -// | { -// Date: string; -// Hourly: number; -// Total: number; -// } -// | { -// Date: string; -// Daily: number; -// Total: number; -// }; - -// export interface NormalizedItem { -// datetime: string; -// value: number; -// max?: number; -// min?: number; -// } - -// export interface Point { -// x: number; -// y: number; -// } - -// interface Location { -// latitude: number; -// longitude: number; -// } - -// export interface GfhStationDetails { -// RIVER_BASIN: string; -// STATION_LOCATIONS_DETAILS: StationLoacationDetails[]; -// } - -// export interface StationLoacationDetails { -// LATITUDE: number; -// POINT_ID: string; -// RIVER_GAUGE_ID?: string; -// LONGITUDE: number; -// RIVER_NAME: string; -// STATION_ID: string; -// STATION_NAME: string; -// 'LISFLOOD_X_(DEG)': number; -// 'LISFLOOD_Y_[DEG]': number; -// LISFLOOD_DRAINAGE_AREA: number; -// } - -// export interface Gauge { -// gaugeId: string; -// location: Location; -// source?: string; -// qualityVerified?: boolean; -// [key: string]: any; -// } - -// interface ForecastRange { -// timeRange?: { -// startTime?: string; -// endTime?: string; -// }; -// trend?: string; -// severity?: string; -// [key: string]: any; -// } - -// export interface Forecast { -// issuedTime: string; -// forecastRanges: ForecastRange[]; -// [key: string]: any; -// } - -// export interface GaugeInfo { -// gaugeId: string; -// distance: number; -// source: string; -// gaugeLocation: Location; -// qualityVerified: boolean; -// } - -// export interface ProcessedForecast { -// issuedTime: string; -// forecastTimeRange: any; -// forecastTrend: string; -// severity: string; -// forecastRanges: ForecastRange[]; -// } - -// export interface GaugeData { -// model_metadata: any; -// all_forecasts: Forecast[]; -// latest_forecast: ProcessedForecast | null; -// } - -// export interface StationResult { -// gaugeId: string; -// distance_km: number; -// source: string; -// gaugeLocation: Location; -// qualityVerified: boolean; -// model_metadata: any; -// issuedTime: string | null; -// forecastTimeRange: any; -// forecastTrend: string; -// severity: string; -// forecasts: ForecastRange[]; -// total_forecasts_available: number; -// message?: string; -// } - -// export interface SearchGaugesRequest { -// regionCode: string; -// pageSize: number; -// includeNonQualityVerified: boolean; -// pageToken?: string; -// } - -// export interface SearchGaugesResponse { -// gauges: Gauge[]; -// nextPageToken?: string; -// } - -// export interface BatchGetResponse { -// gaugeModels: any[]; -// } - -// export interface QueryForecastsResponse { -// forecasts: Record; -// } export interface GfhStationDetails { RIVER_BASIN: string; STATION_LOCATIONS_DETAILS: StationLoacationDetails[]; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 43431ac..4e804d0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -187,12 +187,6 @@ importers: '@lib/database': specifier: workspace:* version: link:../../packages/database - '@lib/dhm-adapter': - specifier: workspace:* - version: link:../../packages/dhm-adapter - '@lib/glofas-adapter': - specifier: workspace:* - version: link:../../packages/glofas-adapter '@nestjs/platform-express': specifier: ^10.3.7 version: 10.4.20(@nestjs/common@10.4.20)(@nestjs/core@10.4.20) From 0d83572155cedfe31b2a401480e357fd6bc66a6c Mon Sep 17 00:00:00 2001 From: Pratiksharai-Rumsan Date: Thu, 4 Dec 2025 09:34:03 +0545 Subject: [PATCH 3/3] add forcast api in swagger --- apps/{mock-api => forcast-api}/.env.example | 0 apps/{mock-api => forcast-api}/.gitignore | 0 apps/{mock-api => forcast-api}/.prettierrc | 0 apps/{mock-api => forcast-api}/README.md | 118 +-------------- .../eslint.config.mjs | 0 apps/{mock-api => forcast-api}/nest-cli.json | 0 apps/{mock-api => forcast-api}/package.json | 2 +- .../src/all-exceptions.filter.ts | 0 .../src/app.controller.ts | 0 .../src/app.module.ts | 3 +- .../src/app.service.ts | 0 .../src/data/dhm/index.ts | 0 .../src/data/gfh/index.ts | 0 .../src/data/glofas/raw-response.ts | 0 .../src/forecast/forecast.controller.ts | 0 .../src/forecast/forecast.module.ts | 0 .../src/forecast/forecast.service.ts | 0 .../src/helpers/wiston.logger.ts | 0 apps/{mock-api => forcast-api}/src/main.ts | 6 +- .../src/types/data-source.ts | 0 .../src/utils/date.ts | 0 .../tsconfig.build.json | 0 apps/{mock-api => forcast-api}/tsconfig.json | 0 .../seeds/seed-mock-datasource-config.ts | 80 +++++++++++ .../prisma/seeds/seed-mock-datasource.ts | 135 ++++++++++++++++++ 25 files changed, 222 insertions(+), 122 deletions(-) rename apps/{mock-api => forcast-api}/.env.example (100%) rename apps/{mock-api => forcast-api}/.gitignore (100%) rename apps/{mock-api => forcast-api}/.prettierrc (100%) rename apps/{mock-api => forcast-api}/README.md (60%) rename apps/{mock-api => forcast-api}/eslint.config.mjs (100%) rename apps/{mock-api => forcast-api}/nest-cli.json (100%) rename apps/{mock-api => forcast-api}/package.json (98%) rename apps/{mock-api => forcast-api}/src/all-exceptions.filter.ts (100%) rename apps/{mock-api => forcast-api}/src/app.controller.ts (100%) rename apps/{mock-api => forcast-api}/src/app.module.ts (88%) rename apps/{mock-api => forcast-api}/src/app.service.ts (100%) rename apps/{mock-api => forcast-api}/src/data/dhm/index.ts (100%) rename apps/{mock-api => forcast-api}/src/data/gfh/index.ts (100%) rename apps/{mock-api => forcast-api}/src/data/glofas/raw-response.ts (100%) rename apps/{mock-api => forcast-api}/src/forecast/forecast.controller.ts (100%) rename apps/{mock-api => forcast-api}/src/forecast/forecast.module.ts (100%) rename apps/{mock-api => forcast-api}/src/forecast/forecast.service.ts (100%) rename apps/{mock-api => forcast-api}/src/helpers/wiston.logger.ts (100%) rename apps/{mock-api => forcast-api}/src/main.ts (92%) rename apps/{mock-api => forcast-api}/src/types/data-source.ts (100%) rename apps/{mock-api => forcast-api}/src/utils/date.ts (100%) rename apps/{mock-api => forcast-api}/tsconfig.build.json (100%) rename apps/{mock-api => forcast-api}/tsconfig.json (100%) create mode 100644 packages/database/prisma/seeds/seed-mock-datasource-config.ts create mode 100644 packages/database/prisma/seeds/seed-mock-datasource.ts diff --git a/apps/mock-api/.env.example b/apps/forcast-api/.env.example similarity index 100% rename from apps/mock-api/.env.example rename to apps/forcast-api/.env.example diff --git a/apps/mock-api/.gitignore b/apps/forcast-api/.gitignore similarity index 100% rename from apps/mock-api/.gitignore rename to apps/forcast-api/.gitignore diff --git a/apps/mock-api/.prettierrc b/apps/forcast-api/.prettierrc similarity index 100% rename from apps/mock-api/.prettierrc rename to apps/forcast-api/.prettierrc diff --git a/apps/mock-api/README.md b/apps/forcast-api/README.md similarity index 60% rename from apps/mock-api/README.md rename to apps/forcast-api/README.md index addbbb3..2341f77 100644 --- a/apps/mock-api/README.md +++ b/apps/forcast-api/README.md @@ -21,7 +21,6 @@ This mock server enables: - ⚡ **Fast Development**: No network latency or API delays - 🎭 **Scenario Simulation**: Test edge cases (high floods, API failures, etc.) - 💰 **Cost Savings**: No API usage costs or rate limit concerns -- 🔒 **Offline Development**: Work without internet connection ## ✨ Features @@ -31,8 +30,6 @@ This mock server enables: - **Swagger Documentation**: Interactive API documentation at `/swagger` - **Winston Logging**: Structured logging for debugging - **CORS Enabled**: Cross-origin requests supported -- **Global Validation**: Request data validation with class-validator -- **Exception Handling**: Comprehensive error handling filters ## 📁 Project Structure @@ -49,45 +46,10 @@ src/ │ ├── forecast.controller.ts # Mock forecast endpoints (GLOFAS, GFH) │ ├── forecast.service.ts # Forecast data service │ └── forecast.module.ts # Forecast module -├── triggers/ -│ ├── triggers.controller.ts # Mock trigger CRUD endpoints -│ ├── trigger.service.ts # Trigger business logic -│ ├── trigger.module.ts # Triggers module -│ └── dto/ -│ └── trigger.dto.ts # Trigger data transfer objects -├── constants/ # Application constants ├── types/ # TypeScript type definitions └── utils/ # Utility functions ``` -## 🔌 API Endpoints - -### Forecast Endpoints (Mock External APIs) - -| Method | Endpoint | Description | Mocks | -| ------ | ----------------------------------------- | ------------------------- | ---------------- | -| `GET` | `/v1/forecast/river` | Get river forecast data | DHM River Watch | -| `GET` | `/v1/forecast/glofas` | Get GLOFAS forecast data | GLOFAS WMS API | -| `POST` | `/v1/forecast/gauges:searchGaugesByArea` | Search GFH gauges by area | Google Flood Hub | -| `GET` | `/v1/forecast/gaugeModels:batchGet` | Get GFH gauge metadata | Google Flood Hub | -| `GET` | `/v1/forecast/gauges:queryGaugeForecasts` | Get GFH gauge forecasts | Google Flood Hub | - -### Trigger Management Endpoints (Testing) - -| Method | Endpoint | Description | -| -------- | ------------------ | ------------------ | -| `GET` | `/v1/triggers` | Get all triggers | -| `GET` | `/v1/triggers/:id` | Get trigger by ID | -| `POST` | `/v1/triggers` | Create new trigger | -| `PATCH` | `/v1/triggers/:id` | Update trigger | -| `DELETE` | `/v1/triggers/:id` | Delete trigger | - -### Health Check - -| Method | Endpoint | Description | -| ------ | -------- | ------------------ | -| `GET` | `/v1` | Basic health check | - ## 🛠️ Environment Configuration Copy the environment example file and update the values: @@ -166,38 +128,6 @@ pnpm dev The server will start at: **`http://localhost:3005`** -### Production Mode - -```bash -# Build first -pnpm --filter mock-api build - -# Start production server -pnpm --filter mock-api start:prod -``` - -### Debug Mode - -```bash -pnpm --filter mock-api dev:debug -``` - -### Testing - -```bash -# Run unit tests -pnpm test - -# Run tests in watch mode -pnpm test:watch - -# Run end-to-end tests -pnpm test:e2e - -# Generate test coverage report -pnpm test:cov -``` - ### Code Quality ```bash @@ -222,7 +152,7 @@ The application provides the following main endpoints: When the application is running, you can access the interactive Swagger documentation at: ``` -http://localhost:3000/swagger +http://localhost:8000/swagger ``` The Swagger UI provides detailed information about all available endpoints, request/response schemas, and allows you to test the API directly from the browser. @@ -247,14 +177,6 @@ The application includes comprehensive error handling: - **Validation Errors**: Automatic validation of request data - **Structured Error Responses**: Consistent error response format -## Logging - -The application uses Winston for structured logging with different log levels: - -- **Development**: Detailed logs with query information -- **Production**: Optimized logging for performance -- **Error Tracking**: Comprehensive error logging with context - ## Development Workflow 1. **Start the database**: Ensure PostgreSQL is running @@ -263,41 +185,3 @@ The application uses Winston for structured logging with different log levels: 4. **Generate Prisma client**: Run `pnpm --filter @lib/database db:generate` 5. **Run migrations**: Run `pnpm --filter @lib/database db:migrate` 6. **Start development server**: Run `pnpm dev` - -## Configuration - -The application can be configured through environment variables: - -- **Database Configuration**: Connection details for PostgreSQL -- **Application Settings**: Port, environment mode, etc. -- **Logging Configuration**: Log levels and output formats - -## Troubleshooting - -### Common Issues - -1. **Port Already in Use**: Change the PORT environment variable -2. **Database Connection Failed**: Verify database configuration and ensure PostgreSQL is running -3. **Build Errors**: Clear node_modules and reinstall dependencies -4. **Migration Issues**: Check database permissions and connection string - -### Debug Mode - -To run the application in debug mode: - -```bash -pnpm start:debug -``` - -This enables the Node.js debugger and provides detailed logging for troubleshooting issues. - -## Production Deployment - -For production deployment: - -1. Set `NODE_ENV=production` in your environment -2. Configure production database settings -3. Build the application: `pnpm build` -4. Start with: `pnpm start:prod` - -The application includes production-optimized logging and error handling when running in production mode. diff --git a/apps/mock-api/eslint.config.mjs b/apps/forcast-api/eslint.config.mjs similarity index 100% rename from apps/mock-api/eslint.config.mjs rename to apps/forcast-api/eslint.config.mjs diff --git a/apps/mock-api/nest-cli.json b/apps/forcast-api/nest-cli.json similarity index 100% rename from apps/mock-api/nest-cli.json rename to apps/forcast-api/nest-cli.json diff --git a/apps/mock-api/package.json b/apps/forcast-api/package.json similarity index 98% rename from apps/mock-api/package.json rename to apps/forcast-api/package.json index 7275868..7f8f997 100644 --- a/apps/mock-api/package.json +++ b/apps/forcast-api/package.json @@ -1,5 +1,5 @@ { - "name": "mock-api", + "name": "forcast-api", "version": "0.0.1", "description": "Nestjs API Seed", "author": "Dipesh Kumar Sah", diff --git a/apps/mock-api/src/all-exceptions.filter.ts b/apps/forcast-api/src/all-exceptions.filter.ts similarity index 100% rename from apps/mock-api/src/all-exceptions.filter.ts rename to apps/forcast-api/src/all-exceptions.filter.ts diff --git a/apps/mock-api/src/app.controller.ts b/apps/forcast-api/src/app.controller.ts similarity index 100% rename from apps/mock-api/src/app.controller.ts rename to apps/forcast-api/src/app.controller.ts diff --git a/apps/mock-api/src/app.module.ts b/apps/forcast-api/src/app.module.ts similarity index 88% rename from apps/mock-api/src/app.module.ts rename to apps/forcast-api/src/app.module.ts index 1ca5614..787b339 100644 --- a/apps/mock-api/src/app.module.ts +++ b/apps/forcast-api/src/app.module.ts @@ -6,6 +6,7 @@ import { PrismaModule } from '@lib/database'; import { ConfigModule } from '@nestjs/config'; import { HttpModule } from '@nestjs/axios'; import { SettingsModule } from '@lib/core'; +import { ForecastModule } from './forecast/forecast.module'; @Module({ imports: [ @@ -18,7 +19,7 @@ import { SettingsModule } from '@lib/core'; HttpModule.register({ global: true, }), - + ForecastModule, SettingsModule, ], controllers: [AppController], diff --git a/apps/mock-api/src/app.service.ts b/apps/forcast-api/src/app.service.ts similarity index 100% rename from apps/mock-api/src/app.service.ts rename to apps/forcast-api/src/app.service.ts diff --git a/apps/mock-api/src/data/dhm/index.ts b/apps/forcast-api/src/data/dhm/index.ts similarity index 100% rename from apps/mock-api/src/data/dhm/index.ts rename to apps/forcast-api/src/data/dhm/index.ts diff --git a/apps/mock-api/src/data/gfh/index.ts b/apps/forcast-api/src/data/gfh/index.ts similarity index 100% rename from apps/mock-api/src/data/gfh/index.ts rename to apps/forcast-api/src/data/gfh/index.ts diff --git a/apps/mock-api/src/data/glofas/raw-response.ts b/apps/forcast-api/src/data/glofas/raw-response.ts similarity index 100% rename from apps/mock-api/src/data/glofas/raw-response.ts rename to apps/forcast-api/src/data/glofas/raw-response.ts diff --git a/apps/mock-api/src/forecast/forecast.controller.ts b/apps/forcast-api/src/forecast/forecast.controller.ts similarity index 100% rename from apps/mock-api/src/forecast/forecast.controller.ts rename to apps/forcast-api/src/forecast/forecast.controller.ts diff --git a/apps/mock-api/src/forecast/forecast.module.ts b/apps/forcast-api/src/forecast/forecast.module.ts similarity index 100% rename from apps/mock-api/src/forecast/forecast.module.ts rename to apps/forcast-api/src/forecast/forecast.module.ts diff --git a/apps/mock-api/src/forecast/forecast.service.ts b/apps/forcast-api/src/forecast/forecast.service.ts similarity index 100% rename from apps/mock-api/src/forecast/forecast.service.ts rename to apps/forcast-api/src/forecast/forecast.service.ts diff --git a/apps/mock-api/src/helpers/wiston.logger.ts b/apps/forcast-api/src/helpers/wiston.logger.ts similarity index 100% rename from apps/mock-api/src/helpers/wiston.logger.ts rename to apps/forcast-api/src/helpers/wiston.logger.ts diff --git a/apps/mock-api/src/main.ts b/apps/forcast-api/src/main.ts similarity index 92% rename from apps/mock-api/src/main.ts rename to apps/forcast-api/src/main.ts index 24db92a..a1475e6 100644 --- a/apps/mock-api/src/main.ts +++ b/apps/forcast-api/src/main.ts @@ -31,10 +31,10 @@ async function bootstrap() { ); const config = new DocumentBuilder() - .setTitle('Rahat Triggers') - .setDescription('The Rahat Triggers API description') + .setTitle('Forcast API') + .setDescription('The Forcast API description') .setVersion('1.0') - .addTag('Triggers') + .addTag('Forcast') .build(); const documentFactory = () => SwaggerModule.createDocument(app, config); diff --git a/apps/mock-api/src/types/data-source.ts b/apps/forcast-api/src/types/data-source.ts similarity index 100% rename from apps/mock-api/src/types/data-source.ts rename to apps/forcast-api/src/types/data-source.ts diff --git a/apps/mock-api/src/utils/date.ts b/apps/forcast-api/src/utils/date.ts similarity index 100% rename from apps/mock-api/src/utils/date.ts rename to apps/forcast-api/src/utils/date.ts diff --git a/apps/mock-api/tsconfig.build.json b/apps/forcast-api/tsconfig.build.json similarity index 100% rename from apps/mock-api/tsconfig.build.json rename to apps/forcast-api/tsconfig.build.json diff --git a/apps/mock-api/tsconfig.json b/apps/forcast-api/tsconfig.json similarity index 100% rename from apps/mock-api/tsconfig.json rename to apps/forcast-api/tsconfig.json diff --git a/packages/database/prisma/seeds/seed-mock-datasource-config.ts b/packages/database/prisma/seeds/seed-mock-datasource-config.ts new file mode 100644 index 0000000..472ae47 --- /dev/null +++ b/packages/database/prisma/seeds/seed-mock-datasource-config.ts @@ -0,0 +1,80 @@ +import { PrismaClient, DataSource, SourceType } from '../../generated/prisma'; +import { DataSourceConfigType } from '../../index'; +const prisma = new PrismaClient(); + +const config: DataSourceConfigType = { + name: 'DATASOURCECONFIG', + value: { + [DataSource.DHM]: { + [SourceType.RAINFALL]: { + URL: 'http://localhost:3005/v1/forecast/river', + }, + [SourceType.WATER_LEVEL]: { + URL: 'http://localhost:3005/v1/forecast/river', + }, + }, + [DataSource.GLOFAS]: { + URL: 'http://localhost:3005/v1/forecast/glofas', + }, + [DataSource.GFH]: { + URL: 'http://localhost:3005/v1/forecast/gauges:queryGaugeForecasts', + }, + }, + isPrivate: false, +}; + +const main = async () => { + console.log('#'.repeat(30)); + console.log('Seeding MOCK DATASOURCE CONFIG'); + console.log('#'.repeat(30)); + + try { + const dataSource = await prisma.mockSetting.findUnique({ + where: { name: config.name }, + }); + + if (dataSource) { + console.log('Mock DataSource Config already exists'); + await prisma.mockSetting.delete({ + where: { name: config.name }, + }); + console.log('Old MOCK DATASOURCE CONFIG deleted'); + } + await prisma.mockSetting.create({ + data: { + name: config.name, + value: config.value, + isPrivate: config.isPrivate, + dataType: 'OBJECT', + requiredFields: [], + isReadOnly: false, + }, + }); + console.log('✅ Mock DataSource Config created successfully'); + } catch (error: any) { + console.error('❌ Error creating mock datasource config:', error); + await prisma.mockSetting.create({ + data: { + name: config.name, + value: config.value, + isPrivate: config.isPrivate, + dataType: 'OBJECT', + requiredFields: [], + isReadOnly: false, + }, + }); + } +}; + +main() + .then(async () => {}) + .catch(async (error) => { + console.log(error); + }) + .finally(async () => { + console.log('#'.repeat(30)); + console.log('Mock seeding completed'); + console.log('#'.repeat(30)); + console.log('\n'); + await prisma.$disconnect(); + }); diff --git a/packages/database/prisma/seeds/seed-mock-datasource.ts b/packages/database/prisma/seeds/seed-mock-datasource.ts new file mode 100644 index 0000000..dd52d81 --- /dev/null +++ b/packages/database/prisma/seeds/seed-mock-datasource.ts @@ -0,0 +1,135 @@ +import { + PrismaClient, + Prisma, + DataSource, + SourceType, +} from '../../generated/prisma'; +import { DataSourceType } from '../../index'; + +const prisma = new PrismaClient(); + +const config: DataSourceType = { + name: 'DATASOURCE', + value: { + [DataSource.DHM]: [ + { + [SourceType.RAINFALL]: { + LOCATION: 'Doda river at East-West Highway', + SERIESID: [29785, 29608, 5726, 29689], + }, + [SourceType.WATER_LEVEL]: { + LOCATION: 'Doda river at East-West Highway', + SERIESID: [29089], + }, + }, + { + [SourceType.RAINFALL]: { + LOCATION: 'Karnali river at Chisapani', + SERIESID: [29785, 29608, 5726, 29689], + }, + [SourceType.WATER_LEVEL]: { + LOCATION: 'Karnali river at Chisapani', + SERIESID: [29089], + }, + }, + ], + [DataSource.GLOFAS]: [ + { + LOCATION: 'Doda river at East-West Highway', + URL: 'http://localhost:3005/v1/forecast/glofas', + BBOX: '8918060.964088082,3282511.7426786087,9006116.420672605,3370567.1992631317', + I: '227', + J: '67', + TIMESTRING: '2023-10-01T00:00:00Z', + }, + ], + [DataSource.GFH]: [ + { + RIVER_BASIN: 'Doda river at East-West Highway', + STATION_LOCATIONS_DETAILS: [ + { + STATION_NAME: 'Doda River Basin', + RIVER_GAUGE_ID: 'hybas_4120803470', + RIVER_NAME: 'doda', + STATION_ID: 'G10165', + POINT_ID: 'SI002576', + LISFLOOD_DRAINAGE_AREA: 432, + 'LISFLOOD_X_(DEG)': 80.422917, + 'LISFLOOD_Y_[DEG]': 28.84375, + LATITUDE: 28.84375, + LONGITUDE: 80.422917, + }, + { + STATION_NAME: 'Sarda River Basin', + RIVER_NAME: 'doda', + STATION_ID: 'G10166', + POINT_ID: 'SI002576', + LISFLOOD_DRAINAGE_AREA: 432, + 'LISFLOOD_X_(DEG)': 80.422917, + 'LISFLOOD_Y_[DEG]': 28.84375, + LATITUDE: 28.84375, + LONGITUDE: 80.422917, + }, + ], + }, + ], + }, + isPrivate: false, +}; + +const main = async () => { + console.log('#'.repeat(30)); + console.log('Seeding MOCK DATASOURCE'); + console.log('#'.repeat(30)); + try { + const dataSource = await prisma.mockSetting.findUnique({ + where: { name: 'DATASOURCE' }, + }); + + if (dataSource) { + console.log('MOCK DATASOURCE already exists'); + await prisma.mockSetting.delete({ + where: { name: 'DATASOURCE' }, + }); + console.log('Old MOCK DATASOURCE deleted'); + } + await prisma.mockSetting.create({ + data: { + name: config.name, + value: config.value as unknown as Prisma.InputJsonValue, + isPrivate: config.isPrivate, + dataType: 'OBJECT', + requiredFields: [], + isReadOnly: false, + }, + }); + console.log('✅ Mock DATASOURCE created successfully'); + } catch (error: any) { + console.error('❌ Error creating mock datasource:', error); + await prisma.mockSetting.create({ + data: { + name: config.name, + value: config.value as unknown as Prisma.InputJsonValue, + isPrivate: config.isPrivate, + dataType: 'OBJECT', + requiredFields: [], + isReadOnly: false, + }, + }); + } +}; + +main() + .catch(async (error) => { + console.log('#'.repeat(30)); + console.log('Error during seeding MOCK DATASOURCE'); + console.log(error); + console.log('#'.repeat(30)); + }) + .finally(async () => { + console.log('#'.repeat(30)); + console.log('Mock seeding completed for DATASOURCE'); + console.log('#'.repeat(30)); + console.log('\n'); + await prisma.$disconnect(); + });