diff --git a/api/apps/api/src/modules/legacy-project-import/domain/events/all-legacy-project-import-pieces-imported.event.ts b/api/apps/api/src/modules/legacy-project-import/domain/events/all-legacy-project-import-pieces-imported.event.ts new file mode 100644 index 0000000000..862e9fad12 --- /dev/null +++ b/api/apps/api/src/modules/legacy-project-import/domain/events/all-legacy-project-import-pieces-imported.event.ts @@ -0,0 +1,10 @@ +import { ResourceId } from '@marxan/cloning/domain'; +import { IEvent } from '@nestjs/cqrs'; +import { LegacyProjectImportId } from '../legacy-project-import/legacy-project-import.id'; + +export class AllLegacyProjectPiecesImported implements IEvent { + constructor( + public readonly legacyProjectImportId: LegacyProjectImportId, + public readonly projectId: ResourceId, + ) {} +} diff --git a/api/apps/api/src/modules/legacy-project-import/domain/events/legacy-project-import-batch-failed.event.ts b/api/apps/api/src/modules/legacy-project-import/domain/events/legacy-project-import-batch-failed.event.ts new file mode 100644 index 0000000000..c25badb4f7 --- /dev/null +++ b/api/apps/api/src/modules/legacy-project-import/domain/events/legacy-project-import-batch-failed.event.ts @@ -0,0 +1,9 @@ +import { IEvent } from '@nestjs/cqrs'; +import { LegacyProjectImportId } from '../legacy-project-import/legacy-project-import.id'; + +export class LegacyProjectImportBatchFailed implements IEvent { + constructor( + public readonly legacyProjectImportId: LegacyProjectImportId, + public readonly batchNumber: number, + ) {} +} diff --git a/api/apps/api/src/modules/legacy-project-import/domain/events/legacy-project-import-piece-imported.event.ts b/api/apps/api/src/modules/legacy-project-import/domain/events/legacy-project-import-piece-imported.event.ts new file mode 100644 index 0000000000..98a81311b0 --- /dev/null +++ b/api/apps/api/src/modules/legacy-project-import/domain/events/legacy-project-import-piece-imported.event.ts @@ -0,0 +1,10 @@ +import { IEvent } from '@nestjs/cqrs'; +import { LegacyProjectImportComponentId } from '../legacy-project-import/legacy-project-import-component.id'; +import { LegacyProjectImportId } from '../legacy-project-import/legacy-project-import.id'; + +export class LegacyProjectImportPieceImported implements IEvent { + constructor( + public readonly legacyProjectImportId: LegacyProjectImportId, + public readonly componentId: LegacyProjectImportComponentId, + ) {} +} diff --git a/api/apps/api/src/modules/legacy-project-import/domain/events/legacy-project-import-piece-requested.event.ts b/api/apps/api/src/modules/legacy-project-import/domain/events/legacy-project-import-piece-requested.event.ts new file mode 100644 index 0000000000..e6f56105e2 --- /dev/null +++ b/api/apps/api/src/modules/legacy-project-import/domain/events/legacy-project-import-piece-requested.event.ts @@ -0,0 +1,10 @@ +import { IEvent } from '@nestjs/cqrs'; +import { LegacyProjectImportComponentId } from '../legacy-project-import/legacy-project-import-component.id'; +import { LegacyProjectImportId } from '../legacy-project-import/legacy-project-import.id'; + +export class LegacyProjectImportPieceRequested implements IEvent { + constructor( + public readonly legacyProjectImportId: LegacyProjectImportId, + public readonly componentId: LegacyProjectImportComponentId, + ) {} +} diff --git a/api/apps/api/src/modules/legacy-project-import/domain/events/legacy-project-import-requested.event.ts b/api/apps/api/src/modules/legacy-project-import/domain/events/legacy-project-import-requested.event.ts new file mode 100644 index 0000000000..b01fe3da9d --- /dev/null +++ b/api/apps/api/src/modules/legacy-project-import/domain/events/legacy-project-import-requested.event.ts @@ -0,0 +1,10 @@ +import { ResourceId } from '@marxan/cloning/domain'; +import { IEvent } from '@nestjs/cqrs'; +import { LegacyProjectImportId } from '../legacy-project-import/legacy-project-import.id'; + +export class LegacyProjectImportRequested implements IEvent { + constructor( + public readonly legacyProjectImportId: LegacyProjectImportId, + public readonly projectId: ResourceId, + ) {} +} diff --git a/api/apps/api/src/modules/legacy-project-import/domain/legacy-project-import/legacy-project-import-component-status.ts b/api/apps/api/src/modules/legacy-project-import/domain/legacy-project-import/legacy-project-import-component-status.ts new file mode 100644 index 0000000000..994b6aab1b --- /dev/null +++ b/api/apps/api/src/modules/legacy-project-import/domain/legacy-project-import/legacy-project-import-component-status.ts @@ -0,0 +1,45 @@ +export enum LegacyProjectImportComponentStatuses { + Submitted = 'submitted', + Completed = 'completed', + Failed = 'failed', +} + +export class LegacyProjectImportComponentStatus { + static create(): LegacyProjectImportComponentStatus { + return new LegacyProjectImportComponentStatus( + LegacyProjectImportComponentStatuses.Submitted, + ); + } + + constructor(private readonly status: LegacyProjectImportComponentStatuses) {} + + markAsCompleted(): LegacyProjectImportComponentStatus { + if (this.status === LegacyProjectImportComponentStatuses.Failed) + throw new Error('Import component has already failed'); + + return new LegacyProjectImportComponentStatus( + LegacyProjectImportComponentStatuses.Completed, + ); + } + + markAsFailed(): LegacyProjectImportComponentStatus { + if (this.status === LegacyProjectImportComponentStatuses.Completed) + throw new Error('Import component has already been completed'); + + return new LegacyProjectImportComponentStatus( + LegacyProjectImportComponentStatuses.Failed, + ); + } + + isReady() { + return this.status === LegacyProjectImportComponentStatuses.Completed; + } + + hasFailed() { + return this.status === LegacyProjectImportComponentStatuses.Failed; + } + + toSnapshot(): LegacyProjectImportComponentStatuses { + return this.status; + } +} diff --git a/api/apps/api/src/modules/legacy-project-import/domain/legacy-project-import/legacy-project-import-component.id.ts b/api/apps/api/src/modules/legacy-project-import/domain/legacy-project-import/legacy-project-import-component.id.ts new file mode 100644 index 0000000000..94fe8e04d8 --- /dev/null +++ b/api/apps/api/src/modules/legacy-project-import/domain/legacy-project-import/legacy-project-import-component.id.ts @@ -0,0 +1,14 @@ +import { v4 } from 'uuid'; + +export class LegacyProjectImportComponentId { + private readonly _token = 'legacy-project-import-component-id'; + constructor(public readonly value: string) {} + + static create(): LegacyProjectImportComponentId { + return new LegacyProjectImportComponentId(v4()); + } + + equals(other: LegacyProjectImportComponentId): boolean { + return this.value === other.value; + } +} diff --git a/api/apps/api/src/modules/legacy-project-import/domain/legacy-project-import/legacy-project-import-component.snapshot.ts b/api/apps/api/src/modules/legacy-project-import/domain/legacy-project-import/legacy-project-import-component.snapshot.ts new file mode 100644 index 0000000000..d5e1dad325 --- /dev/null +++ b/api/apps/api/src/modules/legacy-project-import/domain/legacy-project-import/legacy-project-import-component.snapshot.ts @@ -0,0 +1,11 @@ +import { LegacyProjectImportPiece } from '@marxan/legacy-project-import'; +import { LegacyProjectImportComponentStatuses } from './legacy-project-import-component-status'; + +export interface LegacyProjectImportComponentSnapshot { + readonly id: string; + readonly kind: LegacyProjectImportPiece; + readonly order: number; + readonly status: LegacyProjectImportComponentStatuses; + readonly errors: string[]; + readonly warnings: string[]; +} diff --git a/api/apps/api/src/modules/legacy-project-import/domain/legacy-project-import/legacy-project-import-component.ts b/api/apps/api/src/modules/legacy-project-import/domain/legacy-project-import/legacy-project-import-component.ts new file mode 100644 index 0000000000..1543834cde --- /dev/null +++ b/api/apps/api/src/modules/legacy-project-import/domain/legacy-project-import/legacy-project-import-component.ts @@ -0,0 +1,66 @@ +import { ArchiveLocation } from '@marxan/cloning/domain'; +import { + LegacyProjectImportPiece, + LegacyProjectImportPieceOrderResolver, +} from '@marxan/legacy-project-import'; +import { LegacyProjectImportComponentStatus } from './legacy-project-import-component-status'; +import { LegacyProjectImportComponentId } from './legacy-project-import-component.id'; +import { LegacyProjectImportComponentSnapshot } from './legacy-project-import-component.snapshot'; + +export class LegacyProjectImportComponent { + private constructor( + readonly id: LegacyProjectImportComponentId, + readonly kind: LegacyProjectImportPiece, + readonly order: number, + private status: LegacyProjectImportComponentStatus = LegacyProjectImportComponentStatus.create(), + private errors: string[] = [], + private warnings: string[] = [], + ) {} + + static fromSnapshot(snapshot: LegacyProjectImportComponentSnapshot) { + return new LegacyProjectImportComponent( + new LegacyProjectImportComponentId(snapshot.id), + snapshot.kind, + snapshot.order, + new LegacyProjectImportComponentStatus(snapshot.status), + ); + } + + static newOne(kind: LegacyProjectImportPiece): LegacyProjectImportComponent { + return new LegacyProjectImportComponent( + LegacyProjectImportComponentId.create(), + kind, + LegacyProjectImportPieceOrderResolver.resolveFor(kind), + ); + } + + isReady() { + return this.status.isReady(); + } + + hasFailed() { + return this.status.hasFailed(); + } + + complete(warnings: string[] = []) { + this.status = this.status.markAsCompleted(); + this.warnings.push(...warnings); + } + + markAsFailed(errors: string[] = [], warnings: string[] = []) { + this.status = this.status.markAsFailed(); + this.errors.push(...errors); + this.warnings.push(...warnings); + } + + toSnapshot(): LegacyProjectImportComponentSnapshot { + return { + id: this.id.value, + order: this.order, + status: this.status.toSnapshot(), + kind: this.kind, + errors: this.errors, + warnings: this.warnings, + }; + } +} diff --git a/api/apps/api/src/modules/legacy-project-import/domain/legacy-project-import/legacy-project-import.id.ts b/api/apps/api/src/modules/legacy-project-import/domain/legacy-project-import/legacy-project-import.id.ts new file mode 100644 index 0000000000..efe224d7f7 --- /dev/null +++ b/api/apps/api/src/modules/legacy-project-import/domain/legacy-project-import/legacy-project-import.id.ts @@ -0,0 +1,14 @@ +import { v4 } from 'uuid'; + +export class LegacyProjectImportId { + private readonly _token = 'legacy-project-import-id'; + constructor(public readonly value: string) {} + + static create(): LegacyProjectImportId { + return new LegacyProjectImportId(v4()); + } + + equals(other: LegacyProjectImportId): boolean { + return this.value === other.value; + } +} diff --git a/api/apps/api/src/modules/legacy-project-import/domain/legacy-project-import/legacy-project-import.snapshot.ts b/api/apps/api/src/modules/legacy-project-import/domain/legacy-project-import/legacy-project-import.snapshot.ts new file mode 100644 index 0000000000..88eb502480 --- /dev/null +++ b/api/apps/api/src/modules/legacy-project-import/domain/legacy-project-import/legacy-project-import.snapshot.ts @@ -0,0 +1,12 @@ +import { LegacyProjectImportFileSnapshot } from '@marxan/legacy-project-import'; +import { LegacyProjectImportComponentSnapshot } from './legacy-project-import-component.snapshot'; + +export interface LegacyProjectImportSnapshot { + readonly id: string; + readonly projectId: string; + readonly scenarioId: string; + readonly ownerId: string; + readonly isAcceptingFiles: boolean; + readonly pieces: LegacyProjectImportComponentSnapshot[]; + readonly files: LegacyProjectImportFileSnapshot[]; +} diff --git a/api/apps/api/src/modules/legacy-project-import/domain/legacy-project-import/legacy-project-import.ts b/api/apps/api/src/modules/legacy-project-import/domain/legacy-project-import/legacy-project-import.ts new file mode 100644 index 0000000000..5aac329e1e --- /dev/null +++ b/api/apps/api/src/modules/legacy-project-import/domain/legacy-project-import/legacy-project-import.ts @@ -0,0 +1,278 @@ +import { ArchiveLocation, ResourceId } from '@marxan/cloning/domain'; +import { UserId } from '@marxan/domain-ids'; +import { + LegacyProjectImportFile, + LegacyProjectImportFileType, + LegacyProjectImportPiece, +} from '@marxan/legacy-project-import'; +import { AggregateRoot } from '@nestjs/cqrs'; +import { Either, isLeft, left, right } from 'fp-ts/Either'; +import { AllLegacyProjectPiecesImported } from '../events/all-legacy-project-import-pieces-imported.event'; +import { LegacyProjectImportBatchFailed } from '../events/legacy-project-import-batch-failed.event'; +import { LegacyProjectImportPieceImported } from '../events/legacy-project-import-piece-imported.event'; +import { LegacyProjectImportPieceRequested } from '../events/legacy-project-import-piece-requested.event'; +import { LegacyProjectImportRequested } from '../events/legacy-project-import-requested.event'; +import { LegacyProjectImportComponent } from './legacy-project-import-component'; +import { LegacyProjectImportComponentId } from './legacy-project-import-component.id'; +import { LegacyProjectImportId } from './legacy-project-import.id'; +import { LegacyProjectImportSnapshot } from './legacy-project-import.snapshot'; +export const legacyProjectImportComponentNotFound = Symbol( + `legacy project import component not found`, +); +export const legacyProjectImportComponentAlreadyCompleted = Symbol( + `legacy project import component already completed`, +); +export const legacyProjectImportComponentAlreadyFailed = Symbol( + `legacy project import component already failed`, +); +export const legacyProjectImportDuplicateFile = Symbol( + `legacy project import already has this file`, +); +export const legacyProjectImportDuplicateFileType = Symbol( + `legacy project import already has this file type`, +); +export const legacyProjectImportMissingRequiredFile = Symbol( + `legacy project import missing required file`, +); + +export type CompleteLegacyProjectImportPieceSuccess = true; +export type CompleteLegacyProjectImportPieceErrors = + | typeof legacyProjectImportComponentNotFound + | typeof legacyProjectImportComponentAlreadyCompleted; +export type MarkLegacyProjectImportPieceAsFailedErrors = + | typeof legacyProjectImportComponentNotFound + | typeof legacyProjectImportComponentAlreadyFailed; + +export type AddFileToLegacyProjectImportErrors = + | typeof legacyProjectImportDuplicateFile + | typeof legacyProjectImportDuplicateFileType; + +export type GenerateLegacyProjectImportPiecesErrors = typeof legacyProjectImportMissingRequiredFile; + +export class LegacyProjectImport extends AggregateRoot { + private constructor( + readonly id: LegacyProjectImportId, + private readonly projectId: ResourceId, + private readonly scenarioId: ResourceId, + private readonly ownerId: UserId, + private isAcceptingFiles: boolean = true, + private pieces: LegacyProjectImportComponent[] = [], + private readonly files: LegacyProjectImportFile[] = [], + ) { + super(); + } + + static fromSnapshot( + snapshot: LegacyProjectImportSnapshot, + ): LegacyProjectImport { + return new LegacyProjectImport( + new LegacyProjectImportId(snapshot.id), + new ResourceId(snapshot.projectId), + new ResourceId(snapshot.scenarioId), + new UserId(snapshot.ownerId), + snapshot.isAcceptingFiles, + snapshot.pieces.map(LegacyProjectImportComponent.fromSnapshot), + snapshot.files.map(LegacyProjectImportFile.fromSnapshot), + ); + } + + static newOne( + projectId: ResourceId, + scenarioId: ResourceId, + ownerId: UserId, + ): LegacyProjectImport { + return new LegacyProjectImport( + LegacyProjectImportId.create(), + projectId, + scenarioId, + ownerId, + ); + } + + private requestFirstBatch() { + const firstBatchOrder = Math.min( + ...this.pieces.map((piece) => piece.order), + ); + + for (const component of this.pieces.filter( + (pc) => pc.order === firstBatchOrder, + )) { + this.apply(new LegacyProjectImportPieceRequested(this.id, component.id)); + } + } + + private hasBatchFinished(order: number) { + return this.pieces + .filter((piece) => piece.order === order) + .every((piece) => piece.isReady() || piece.hasFailed()); + } + + private isLastBatch(order: number) { + return order === Math.max(...this.pieces.map((piece) => piece.order)); + } + + private hasBatchFailed(order: number) { + return this.pieces + .filter((piece) => piece.order === order) + .some((piece) => piece.hasFailed()); + } + + private areRequiredFilesPresent(): boolean { + const requiredFilesTypes = [ + LegacyProjectImportFileType.PlanningGridShapefile, + LegacyProjectImportFileType.InputDat, + LegacyProjectImportFileType.PuDat, + LegacyProjectImportFileType.PuvsprDat, + LegacyProjectImportFileType.SpecDat, + ]; + const filesTypes = this.files.map((file) => file.type); + + return requiredFilesTypes.every((type) => filesTypes.includes(type)); + } + + private generatePieces(): Either< + GenerateLegacyProjectImportPiecesErrors, + LegacyProjectImportComponent[] + > { + const areRequiredFilesPresent = this.areRequiredFilesPresent(); + if (!areRequiredFilesPresent) + return left(legacyProjectImportMissingRequiredFile); + + const pieces: LegacyProjectImportComponent[] = [ + LegacyProjectImportComponent.newOne( + LegacyProjectImportPiece.PlanningGrid, + ), + LegacyProjectImportComponent.newOne( + LegacyProjectImportPiece.ScenarioPusData, + ), + LegacyProjectImportComponent.newOne(LegacyProjectImportPiece.Features), + LegacyProjectImportComponent.newOne( + LegacyProjectImportPiece.FeaturesSpecification, + ), + ]; + + const solutionsFile = this.files.find( + (file) => file.type === LegacyProjectImportFileType.Output, + ); + if (solutionsFile) { + pieces.push( + LegacyProjectImportComponent.newOne(LegacyProjectImportPiece.Solutions), + ); + } + + return right(pieces); + } + + start(): Either { + this.isAcceptingFiles = false; + const piecesOrError = this.generatePieces(); + + if (isLeft(piecesOrError)) return piecesOrError; + + this.pieces = piecesOrError.right; + + this.apply(new LegacyProjectImportRequested(this.id, this.projectId)); + this.requestFirstBatch(); + + return right(true); + } + + markPieceAsFailed( + pieceId: LegacyProjectImportComponentId, + ): Either { + const piece = this.pieces.find((pc) => pc.id.value === pieceId.value); + if (!piece) return left(legacyProjectImportComponentNotFound); + if (piece.hasFailed()) + return left(legacyProjectImportComponentAlreadyFailed); + + piece.markAsFailed(); + + const hasThisBatchFinished = this.hasBatchFinished(piece.order); + const hasThisBatchFailed = this.hasBatchFailed(piece.order); + + if (hasThisBatchFinished && hasThisBatchFailed) { + this.apply(new LegacyProjectImportBatchFailed(this.id, piece.order)); + } + + return right(true); + } + + completePiece( + pieceId: LegacyProjectImportComponentId, + ): Either< + CompleteLegacyProjectImportPieceErrors, + CompleteLegacyProjectImportPieceSuccess + > { + const pieceToComplete = this.pieces.find( + (pc) => pc.id.value === pieceId.value, + ); + if (!pieceToComplete) return left(legacyProjectImportComponentNotFound); + if (pieceToComplete.isReady()) + return left(legacyProjectImportComponentAlreadyCompleted); + + this.apply(new LegacyProjectImportPieceImported(this.id, pieceId)); + + pieceToComplete.complete(); + + const isThisTheLastBatch = this.isLastBatch(pieceToComplete.order); + const hasThisBatchFinished = this.hasBatchFinished(pieceToComplete.order); + const hasThisBatchFailed = this.hasBatchFailed(pieceToComplete.order); + + if (hasThisBatchFinished && hasThisBatchFailed) { + this.apply( + new LegacyProjectImportBatchFailed(this.id, pieceToComplete.order), + ); + return right(true); + } + + if (isThisTheLastBatch && hasThisBatchFinished) + this.apply(new AllLegacyProjectPiecesImported(this.id, this.projectId)); + if (isThisTheLastBatch || !hasThisBatchFinished) return right(true); + + const nextBatch = this.pieces.filter( + (piece) => piece.order === pieceToComplete.order + 1, + ); + + for (const component of nextBatch) { + this.apply(new LegacyProjectImportPieceRequested(this.id, component.id)); + } + + return right(true); + } + + toSnapshot(): LegacyProjectImportSnapshot { + return { + id: this.id.value, + projectId: this.projectId.value, + scenarioId: this.scenarioId.value, + ownerId: this.ownerId.value, + isAcceptingFiles: this.isAcceptingFiles, + pieces: this.pieces.map((piece) => piece.toSnapshot()), + files: this.files.map((file) => file.toSnapshot()), + }; + } + + addFile( + file: LegacyProjectImportFile, + ): Either { + const fileTypeAlreadyPresent = this.files.some( + (el) => el.type === file.type, + ); + + if (fileTypeAlreadyPresent) { + return left(legacyProjectImportDuplicateFileType); + } + + const duplicateArchiveLocation = this.files.some( + (el) => el.location === file.location, + ); + + if (duplicateArchiveLocation) { + return left(legacyProjectImportDuplicateFile); + } + + this.files.push(file); + + return right(true); + } +} diff --git a/api/libs/legacy-project-import/src/domain/index.ts b/api/libs/legacy-project-import/src/domain/index.ts index e00c5c6247..8df881b1bd 100644 --- a/api/libs/legacy-project-import/src/domain/index.ts +++ b/api/libs/legacy-project-import/src/domain/index.ts @@ -1,6 +1,7 @@ +export { LegacyProjectImportFile } from './legacy-project-import-file'; +export { LegacyProjectImportFileType } from './legacy-project-import-file-type'; +export { LegacyProjectImportFileSnapshot } from './legacy-project-import-file.snapshot'; export { LegacyProjectImportPiece, - LegacyProjectImportPieceRelativePathResolver, LegacyProjectImportPieceOrderResolver, } from './legacy-project-import-piece'; -export { LegacyProjectImportPieceId } from './legacy-project-import-piece.id'; diff --git a/api/libs/legacy-project-import/src/domain/legacy-project-import-file-type.ts b/api/libs/legacy-project-import/src/domain/legacy-project-import-file-type.ts new file mode 100644 index 0000000000..c3117844dc --- /dev/null +++ b/api/libs/legacy-project-import/src/domain/legacy-project-import-file-type.ts @@ -0,0 +1,8 @@ +export enum LegacyProjectImportFileType { + PlanningGridShapefile = 'planning-grid-shapefile', + InputDat = 'input-dat', + PuDat = 'pu-dat', + SpecDat = 'spec-dat', + PuvsprDat = 'puvspr-dat', + Output = 'output', +} diff --git a/api/libs/legacy-project-import/src/domain/legacy-project-import-file.snapshot.ts b/api/libs/legacy-project-import/src/domain/legacy-project-import-file.snapshot.ts new file mode 100644 index 0000000000..669cd4241b --- /dev/null +++ b/api/libs/legacy-project-import/src/domain/legacy-project-import-file.snapshot.ts @@ -0,0 +1,6 @@ +import { LegacyProjectImportFileType } from './legacy-project-import-file-type'; + +export interface LegacyProjectImportFileSnapshot { + location: string; + type: LegacyProjectImportFileType; +} diff --git a/api/libs/legacy-project-import/src/domain/legacy-project-import-file.ts b/api/libs/legacy-project-import/src/domain/legacy-project-import-file.ts new file mode 100644 index 0000000000..6a040b8ab4 --- /dev/null +++ b/api/libs/legacy-project-import/src/domain/legacy-project-import-file.ts @@ -0,0 +1,26 @@ +import { ArchiveLocation } from '../../../cloning/src/domain'; +import { LegacyProjectImportFileType } from './legacy-project-import-file-type'; +import { LegacyProjectImportFileSnapshot } from './legacy-project-import-file.snapshot'; + +export class LegacyProjectImportFile { + constructor( + readonly type: LegacyProjectImportFileType, + readonly location: ArchiveLocation, + ) {} + + toSnapshot(): LegacyProjectImportFileSnapshot { + return { + location: this.location.value, + type: this.type, + }; + } + + static fromSnapshot( + snapshot: LegacyProjectImportFileSnapshot, + ): LegacyProjectImportFile { + return new LegacyProjectImportFile( + snapshot.type, + new ArchiveLocation(snapshot.location), + ); + } +} diff --git a/api/libs/legacy-project-import/src/domain/legacy-project-import-piece.id.ts b/api/libs/legacy-project-import/src/domain/legacy-project-import-piece.id.ts deleted file mode 100644 index 504e88c64f..0000000000 --- a/api/libs/legacy-project-import/src/domain/legacy-project-import-piece.id.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { v4 } from 'uuid'; - -export class LegacyProjectImportPieceId { - private readonly _token = 'legacy-project-import-piece-id'; - constructor(public readonly value: string) {} - - static create(): LegacyProjectImportPieceId { - return new LegacyProjectImportPieceId(v4()); - } - - equals(other: LegacyProjectImportPieceId): boolean { - return this.value === other.value; - } -} diff --git a/api/libs/legacy-project-import/src/domain/legacy-project-import-piece.ts b/api/libs/legacy-project-import/src/domain/legacy-project-import-piece.ts index f164fd6787..9a8637f1f9 100644 --- a/api/libs/legacy-project-import/src/domain/legacy-project-import-piece.ts +++ b/api/libs/legacy-project-import/src/domain/legacy-project-import-piece.ts @@ -1,10 +1,23 @@ -export enum LegacyProjectImportPiece {} +export enum LegacyProjectImportPiece { + PlanningGrid = 'planning-grid', + Features = 'features', + ScenarioPusData = 'scenario-pus-data', + FeaturesSpecification = 'features-specification', + Solutions = 'solutions', +} export class LegacyProjectImportPieceOrderResolver { private static legacyProjectImportPieceOrder: Record< LegacyProjectImportPiece, number - > = {}; + > = { + // TODO Establish proper order for pieces + [LegacyProjectImportPiece.PlanningGrid]: 0, + [LegacyProjectImportPiece.Features]: 1, + [LegacyProjectImportPiece.ScenarioPusData]: 1, + [LegacyProjectImportPiece.FeaturesSpecification]: 2, + [LegacyProjectImportPiece.Solutions]: 2, + }; static resolveFor( legacyProjectImportPiece: LegacyProjectImportPiece, @@ -12,16 +25,3 @@ export class LegacyProjectImportPieceOrderResolver { return this.legacyProjectImportPieceOrder[legacyProjectImportPiece]; } } - -export class LegacyProjectImportPieceRelativePathResolver { - private static legacyProjectImportPieceRelativePaths: Record< - LegacyProjectImportPiece, - string - > = {}; - - static resolveFor( - legacyProjectImportPiece: LegacyProjectImportPiece, - ): string { - return this.legacyProjectImportPieceRelativePaths[legacyProjectImportPiece]; - } -} diff --git a/api/libs/legacy-project-import/src/index.ts b/api/libs/legacy-project-import/src/index.ts index 478ad5e532..3aa9636e40 100644 --- a/api/libs/legacy-project-import/src/index.ts +++ b/api/libs/legacy-project-import/src/index.ts @@ -1,10 +1,6 @@ export { legacyProjectImportQueueName } from './legacy-project-import-queue-name'; export { LegacyProjectImportJobInput } from './job-input'; export { LegacyProjectImportJobOutput } from './job-output'; -export { - LegacyProjectImportPiece, - LegacyProjectImportPieceOrderResolver, - LegacyProjectImportPieceRelativePathResolver, - LegacyProjectImportPieceId, -} from './domain'; +export * from './domain'; +export { LegacyProjectImportFileType } from './domain/legacy-project-import-file-type'; export { LegacyProjectImportPieceProcessor } from './legacy-project-import-piece-processor.port'; diff --git a/api/libs/legacy-project-import/src/job-input.ts b/api/libs/legacy-project-import/src/job-input.ts index 15358cd0b0..7385be1638 100644 --- a/api/libs/legacy-project-import/src/job-input.ts +++ b/api/libs/legacy-project-import/src/job-input.ts @@ -1,9 +1,11 @@ -import { LegacyProjectImportPiece } from './domain'; +import { LegacyProjectImportFileSnapshot } from './domain'; +import { LegacyProjectImportPiece } from './domain/legacy-project-import-piece'; export interface LegacyProjectImportJobInput { readonly legacyProjectImportId: string; readonly pieceId: string; - readonly resourceId: string; + readonly files: LegacyProjectImportFileSnapshot[]; readonly projectId: string; + readonly scenarioId: string; readonly piece: LegacyProjectImportPiece; } diff --git a/api/libs/legacy-project-import/src/job-output.ts b/api/libs/legacy-project-import/src/job-output.ts index c70f75c886..30c4882caf 100644 --- a/api/libs/legacy-project-import/src/job-output.ts +++ b/api/libs/legacy-project-import/src/job-output.ts @@ -1,9 +1,11 @@ -import { LegacyProjectImportPiece } from './domain'; +import { LegacyProjectImportFileSnapshot } from './domain/legacy-project-import-file.snapshot'; +import { LegacyProjectImportPiece } from './domain/legacy-project-import-piece'; export interface LegacyProjectImportJobOutput { readonly legacyProjectImportId: string; - readonly projectId: string; - readonly resourceId: string; readonly pieceId: string; + readonly files: LegacyProjectImportFileSnapshot[]; + readonly projectId: string; + readonly scenarioId: string; readonly piece: LegacyProjectImportPiece; } diff --git a/api/libs/legacy-project-import/src/legacy-project-import-piece-processor.port.ts b/api/libs/legacy-project-import/src/legacy-project-import-piece-processor.port.ts index 2304537df9..cad0869cc4 100644 --- a/api/libs/legacy-project-import/src/legacy-project-import-piece-processor.port.ts +++ b/api/libs/legacy-project-import/src/legacy-project-import-piece-processor.port.ts @@ -1,4 +1,4 @@ -import { LegacyProjectImportPiece } from './domain'; +import { LegacyProjectImportPiece } from './domain/legacy-project-import-piece'; export abstract class LegacyProjectImportPieceProcessor { abstract run(input: I): Promise;