Skip to content

Commit

Permalink
fix(Features): Makes the upload of features (shapefile and csv) async…
Browse files Browse the repository at this point in the history
…hronous
  • Loading branch information
KevSanchez committed Mar 1, 2024
1 parent 8805e10 commit 5578410
Show file tree
Hide file tree
Showing 32 changed files with 952 additions and 239 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class AddFeatureShapefileApiEvents1708099064649
implements MigrationInterface
{
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
INSERT INTO api_event_kinds (id) values
('features.shapefile.import.submitted/v1/alpha'),
('features.shapefile.import.finished/v1/alpha'),
('features.shapefile.import.failed/v1/alpha')
`);

await queryRunner.query(`
UPDATE features SET creation_status = 'created'
WHERE creation_status = 'done';
`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
DELETE FROM api_event_kinds WHERE id IN (
'features.shapefile.import.submitted/v1/alpha',
'features.shapefile.import.finished/v1/alpha',
'features.shapefile.import.failed/v1/alpha')
`);
await queryRunner.query(`
UPDATE features SET creation_status = 'done'
WHERE creation_status = 'created';
`);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
projectNotVisible,
} from '@marxan-api/modules/projects/projects.service';
import { UpdateProjectTagDTO } from '@marxan-api/modules/projects/dto/update-project-tag.dto';
import { JobStatus } from '@marxan-api/modules/scenarios/scenario.api.entity';

export const featureNotFoundWithinProject = Symbol(
'feature not found within project',
Expand Down Expand Up @@ -57,7 +58,11 @@ export class GeoFeatureTagsService {
.createQueryBuilder('feature_tag')
.select('feature_tag.tag', 'tag')
.distinct(true)
.where({ projectId });
.innerJoin(GeoFeature, 'f', 'feature_tag.featureId = f.id')
.where(
'feature_tag.projectId = :projectId and f.creationStatus = :creationStatus',
{ projectId, creationStatus: JobStatus.created },
);

/** @debt
* Even tho this is a highly focused endpoint returning only a list of, it should conform to JSON:API standards as well
Expand Down Expand Up @@ -118,9 +123,15 @@ export class GeoFeatureTagsService {
return left(projectNotEditable);
}

await this.geoFeatureTagsRepo.update(
{ projectId, tag: dto.tagName },
{ tag: dto.updatedTagName },
/**
* @debt ? apparently joins in update queries are currently not supported by typeorm yet, so qe require raw SQL here
*/
await this.geoFeatureTagsRepo.query(
`UPDATE project_feature_tags pft
SET tag = $1
FROM features f
WHERE f.id = pft.feature_id and pft.project_id = $2 and pft.tag = $3 and f.creation_status = $4`,
[dto.updatedTagName, projectId, dto.tagName, JobStatus.created],
);

return right(true);
Expand All @@ -142,7 +153,7 @@ export class GeoFeatureTagsService {
where: { id: featureId, projectId },
});

if (!geoFeature) {
if (!geoFeature || geoFeature.creationStatus !== JobStatus.created) {
return left(featureNotFoundWithinProject);
}

Expand Down Expand Up @@ -206,7 +217,7 @@ export class GeoFeatureTagsService {
where: { id: featureId, projectId },
});

if (!geoFeature) {
if (!geoFeature || geoFeature.creationStatus !== JobStatus.created) {
return left(featureNotFoundWithinProject);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Injectable } from '@nestjs/common';
import { API_EVENT_KINDS } from '@marxan/api-events';
import { ApiEventsService } from '@marxan-api/modules/api-events';
import {
FeatureShapefileImportEventsPort,
FeatureShapefileImportState,
} from '@marxan-api/modules/geo-features/ports/feature-shapefile-import-events-port';

@Injectable()
export class FeatureShapefileImportApiEvents
extends ApiEventsService
implements FeatureShapefileImportEventsPort
{
private readonly eventsMap: Record<
FeatureShapefileImportState,
API_EVENT_KINDS
> = {
[FeatureShapefileImportState.FeatureShapefileSubmitted]:
API_EVENT_KINDS.features__shapefile__import__submitted__v1__alpha,
[FeatureShapefileImportState.FeatureShapefileFinished]:
API_EVENT_KINDS.features__shapefile__import__finished__v1__alpha,
[FeatureShapefileImportState.FeatureShapefileFailed]:
API_EVENT_KINDS.features__shapefile__import__failed__v1__alpha,
};

async event(
projectId: string,
state: FeatureShapefileImportState,
context?: Record<string, unknown>,
): Promise<void> {
await this.create({
data: context ?? {},
topic: projectId,
kind: this.eventsMap[state],
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Module } from '@nestjs/common';
import { ApiEventsModule } from '../../api-events';
import { FeatureShapefileImportEventsPort } from '@marxan-api/modules/geo-features/ports/feature-shapefile-import-events-port';
import { FeatureShapefileImportApiEvents } from '@marxan-api/modules/geo-features/adapters/feature-shapefile-upload-api-events';

@Module({
imports: [ApiEventsModule],
providers: [
{
provide: FeatureShapefileImportEventsPort,
useClass: FeatureShapefileImportApiEvents,
},
],
exports: [FeatureShapefileImportEventsPort],
})
export class GeoFeaturesAdaptersModule {}
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ export interface GeoFeaturesRequestInfo extends AppInfoDTO {
projectId?: string;
bbox?: BBox;
ids?: string[];
includeInProgress?: boolean;
};
}
8 changes: 6 additions & 2 deletions api/apps/api/src/modules/geo-features/geo-features.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ import { FeatureAmountUploadRegistry } from '@marxan-api/modules/geo-features/im
import { UploadedFeatureAmount } from '@marxan-api/modules/geo-features/import/features-amounts-data.api.entity';
import { FeatureAmountUploadService } from '@marxan-api/modules/geo-features/import/features-amounts-upload.service';
import { ApiEventsModule } from '@marxan-api/modules/api-events';
import { FeatureImportEventsService } from '@marxan-api/modules/geo-features/import/feature-import.events';
import { FeatureAmountsPerPlanningUnitModule } from '@marxan/feature-amounts-per-planning-unit';
import { ShapefilesModule } from '@marxan/shapefile-converter';
import { GeoFeaturesAdaptersModule } from '@marxan-api/modules/geo-features/adapters/geo-features-adapters.module';
import { FeatureCSVImportEventsService } from '@marxan-api/modules/geo-features/import/feature-csv-import.events';

@Module({
imports: [
Expand All @@ -45,7 +47,9 @@ import { FeatureAmountsPerPlanningUnitModule } from '@marxan/feature-amounts-per
forwardRef(() => ScenarioFeaturesModule),
ApiEventsModule,
GeoFeatureTagsModule,
ShapefilesModule,
FeatureAmountsPerPlanningUnitModule.for(DbConnections.geoprocessingDB),
GeoFeaturesAdaptersModule,
],
providers: [
GeoFeaturesService,
Expand All @@ -54,7 +58,7 @@ import { FeatureAmountsPerPlanningUnitModule } from '@marxan/feature-amounts-per
GeoFeaturePropertySetService,
ProxyService,
FeatureAmountUploadService,
FeatureImportEventsService,
FeatureCSVImportEventsService,
],
controllers: [GeoFeaturesController],
exports: [
Expand Down
Loading

0 comments on commit 5578410

Please sign in to comment.