diff --git a/api/src/app.module.ts b/api/src/app.module.ts index b80e9e43..4bb384e8 100644 --- a/api/src/app.module.ts +++ b/api/src/app.module.ts @@ -11,6 +11,7 @@ import { UsersModule } from '@api/modules/users/users.module'; import { APP_FILTER } from '@nestjs/core'; import { AllExceptionsFilter } from '@api/filters/all-exceptions.exception.filter'; import { TsRestModule } from '@ts-rest/nest'; +import { CountriesModule } from './modules/countries/countries.module'; @Module({ imports: [ @@ -27,6 +28,7 @@ import { TsRestModule } from '@ts-rest/nest'; AdminModule, ImportModule, UsersModule, + CountriesModule, ], controllers: [AppController], providers: [ diff --git a/api/src/modules/countries/countries.controller.ts b/api/src/modules/countries/countries.controller.ts new file mode 100644 index 00000000..2d0e5cec --- /dev/null +++ b/api/src/modules/countries/countries.controller.ts @@ -0,0 +1,4 @@ +import { Controller } from '@nestjs/common'; + +@Controller('countries') +export class CountriesController {} diff --git a/api/src/modules/countries/countries.module.ts b/api/src/modules/countries/countries.module.ts new file mode 100644 index 00000000..5a8ae4b0 --- /dev/null +++ b/api/src/modules/countries/countries.module.ts @@ -0,0 +1,16 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { Country } from '@shared/entities/countries/country.entity'; +import { CountriesController } from '@api/modules/countries/countries.controller'; + +import { MapController } from './map/map.controller'; +import { CountryRepository } from '@api/modules/countries/countries.repository'; +import { MapRepository } from '@api/modules/countries/map/map.repository'; + +@Module({ + imports: [TypeOrmModule.forFeature([Country])], + controllers: [CountriesController, MapController], + providers: [CountryRepository, MapRepository], + exports: [], +}) +export class CountriesModule {} diff --git a/api/src/modules/countries/countries.repository.ts b/api/src/modules/countries/countries.repository.ts new file mode 100644 index 00000000..e90ecf6b --- /dev/null +++ b/api/src/modules/countries/countries.repository.ts @@ -0,0 +1,14 @@ +import { Injectable } from '@nestjs/common'; +import { Repository } from 'typeorm'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Country } from '@shared/entities/countries/country.entity'; + +@Injectable() +export class CountryRepository extends Repository { + constructor( + @InjectRepository(Country) + private readonly repository: Repository, + ) { + super(repository.target, repository.manager, repository.queryRunner); + } +} diff --git a/api/src/modules/countries/map/map.controller.ts b/api/src/modules/countries/map/map.controller.ts new file mode 100644 index 00000000..5fa16e36 --- /dev/null +++ b/api/src/modules/countries/map/map.controller.ts @@ -0,0 +1,9 @@ +import { Controller, Get } from '@nestjs/common'; + +@Controller('map') +export class MapController { + @Get('/geojson') + getGeoJson() { + return 'This will return the geojson of the countries'; + } +} diff --git a/api/src/modules/countries/map/map.repository.ts b/api/src/modules/countries/map/map.repository.ts new file mode 100644 index 00000000..f10c1d64 --- /dev/null +++ b/api/src/modules/countries/map/map.repository.ts @@ -0,0 +1,14 @@ +import { Injectable } from '@nestjs/common'; +import { Repository } from 'typeorm'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Country } from '@shared/entities/countries/country.entity'; + +@Injectable() +export class MapRepository extends Repository { + constructor( + @InjectRepository(Country) + private readonly repository: Repository, + ) { + super(repository.target, repository.manager, repository.queryRunner); + } +} diff --git a/api/src/modules/import/import.service.ts b/api/src/modules/import/import.service.ts index abb65cac..f8afb239 100644 --- a/api/src/modules/import/import.service.ts +++ b/api/src/modules/import/import.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@nestjs/common'; +import { Injectable, ServiceUnavailableException } from '@nestjs/common'; import { XlsxParser } from '@api/modules/import/services/xlsx.parser'; import { EntityPreprocessor } from '@api/modules/import/services/entity.preprocessor'; import { BaseDataRepository } from '@api/modules/model/base-data.repository'; @@ -21,6 +21,7 @@ export class ImportService { return dbResult; } catch (e) { console.log(e); + throw new ServiceUnavailableException('Error importing data'); } finally { } } diff --git a/api/src/modules/import/services/entity.preprocessor.ts b/api/src/modules/import/services/entity.preprocessor.ts index 0fbe007c..cb01fef0 100644 --- a/api/src/modules/import/services/entity.preprocessor.ts +++ b/api/src/modules/import/services/entity.preprocessor.ts @@ -1,6 +1,6 @@ import { Injectable } from '@nestjs/common'; import { BaseData } from '@api/modules/model/base-data.entity'; -import { Country } from '@api/modules/model/entities/country.entity'; +import { Country } from '@shared/entities/countries/country.entity'; export type ParsedDBEntities = { countries: Country[]; diff --git a/api/src/modules/model/base-data.entity.ts b/api/src/modules/model/base-data.entity.ts index 583194c8..c82d0654 100644 --- a/api/src/modules/model/base-data.entity.ts +++ b/api/src/modules/model/base-data.entity.ts @@ -5,7 +5,7 @@ import { ManyToOne, JoinColumn, } from 'typeorm'; -import { Country } from '@api/modules/model/entities/country.entity'; +import { Country } from '@shared/entities/countries/country.entity'; export enum ECOSYSTEM { MANGROVE = 'Mangrove', diff --git a/api/src/modules/model/base-data.repository.ts b/api/src/modules/model/base-data.repository.ts index 3126fe72..1cac5d4e 100644 --- a/api/src/modules/model/base-data.repository.ts +++ b/api/src/modules/model/base-data.repository.ts @@ -3,7 +3,6 @@ import { Injectable } from '@nestjs/common'; import { ParsedDBEntities } from '@api/modules/import/services/entity.preprocessor'; import { BaseData } from '@api/modules/model/base-data.entity'; -import { Country } from '@api/modules/model/entities/country.entity'; import { COST_INPUT_TYPE, CostInput, @@ -12,6 +11,7 @@ import { CARBON_INPUT_TYPE, CarbonInputEntity, } from '@api/modules/model/entities/carbon-input.entity'; +import { Country } from '@shared/entities/countries/country.entity'; @Injectable() export class BaseDataRepository extends Repository { diff --git a/api/src/modules/model/entities/carbon-input.entity.ts b/api/src/modules/model/entities/carbon-input.entity.ts index b5078032..8882c34e 100644 --- a/api/src/modules/model/entities/carbon-input.entity.ts +++ b/api/src/modules/model/entities/carbon-input.entity.ts @@ -8,7 +8,7 @@ import { BaseEntity, } from 'typeorm'; import { ACTIVITY, ECOSYSTEM } from '@api/modules/model/base-data.entity'; -import { Country } from '@api/modules/model/entities/country.entity'; +import { Country } from '@shared/entities/countries/country.entity'; export enum CARBON_INPUT_TYPE { ECOSYSTEM_EXTENT = 'ecosystem_extent', diff --git a/api/src/modules/model/entities/cost-input.entity.ts b/api/src/modules/model/entities/cost-input.entity.ts index 67ef86ec..e64202ce 100644 --- a/api/src/modules/model/entities/cost-input.entity.ts +++ b/api/src/modules/model/entities/cost-input.entity.ts @@ -8,7 +8,7 @@ import { BaseEntity, } from 'typeorm'; import { ACTIVITY, ECOSYSTEM } from '@api/modules/model/base-data.entity'; -import { Country } from '@api/modules/model/entities/country.entity'; +import { Country } from '@shared/entities/countries/country.entity'; export enum COST_INPUT_TYPE { PROJECT_SIZE_HA = 'project_size_ha', diff --git a/api/src/modules/model/entities/country.entity.ts b/shared/entities/countries/country.entity.ts similarity index 78% rename from api/src/modules/model/entities/country.entity.ts rename to shared/entities/countries/country.entity.ts index 4edbf241..512ef552 100644 --- a/api/src/modules/model/entities/country.entity.ts +++ b/shared/entities/countries/country.entity.ts @@ -1,4 +1,11 @@ -import { Column, Entity, PrimaryColumn, BaseEntity } from 'typeorm'; +import { + Column, + Entity, + PrimaryColumn, + BaseEntity, + Geometry, + Index, +} from 'typeorm'; export enum CONTINENTS { AFRICA = 'Africa', @@ -34,4 +41,13 @@ export class Country extends BaseEntity { @Column({ name: 'hdi', type: 'int', nullable: true }) hdi?: number; + + @Index({ spatial: true }) + @Column({ + type: 'geometry', + srid: 4326, + // TODO: Make it nullable false once we have all the data + nullable: true, + }) + geometry: Geometry; } diff --git a/shared/entities/database.entities.ts b/shared/entities/database.entities.ts index 9b7568eb..66fc0bde 100644 --- a/shared/entities/database.entities.ts +++ b/shared/entities/database.entities.ts @@ -1,3 +1,4 @@ import { User } from "@shared/entities/users/user.entity"; +import { Country } from "@shared/entities/countries/country.entity"; -export const COMMON_DATABASE_ENTITIES = [User]; +export const COMMON_DATABASE_ENTITIES = [User, Country]; diff --git a/shared/lib/db-entities.ts b/shared/lib/db-entities.ts index 6b83fdb5..f1ae4140 100644 --- a/shared/lib/db-entities.ts +++ b/shared/lib/db-entities.ts @@ -1,9 +1,9 @@ import { User } from "@shared/entities/users/user.entity"; import { ApiEventsEntity } from "@api/modules/api-events/api-events.entity"; -import { Country } from "@api/modules/model/entities/country.entity"; import { BaseData } from "@api/modules/model/base-data.entity"; import { CostInput } from "@api/modules/model/entities/cost-input.entity"; import { CarbonInputEntity } from "@api/modules/model/entities/carbon-input.entity"; +import { Country } from "@shared/entities/countries/country.entity"; export const DB_ENTITIES = [ User,