Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adding polygon-parts table name type and valdiation #241

Merged
merged 11 commits into from
Nov 28, 2024
27 changes: 0 additions & 27 deletions src/models/polygonParts/aggregationLayerMetadata.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/models/polygonParts/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export type { AggregationLayerMetadata } from './aggregationLayerMetadata';
export * from './polygonPartRecord';
8 changes: 1 addition & 7 deletions src/models/polygonParts/polygonPartRecord.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
import { Polygon } from 'geojson';
import { keys } from 'ts-transformer-keys';
import { graphql } from '../common/decorators/graphQL/graphql.decorator';
import {
FieldCategory,
IFieldConfigInfo,
IPropFieldConfigInfo,
fieldConfig,
getFieldConfig,
} from '../common/decorators/fieldConfig/fieldConfig.decorator';
import { FieldCategory, IPropFieldConfigInfo, fieldConfig, getFieldConfig } from '../common/decorators/fieldConfig/fieldConfig.decorator';
import { DataFileType, IPropSHPMapping, getInputDataMapping, inputDataMapping } from '../layerMetadata/decorators/property/shp.decorator';
import { catalogDB, getCatalogDBMapping, ORMColumnType } from '../layerMetadata/decorators/property/catalogDB.decorator';
import { getTsTypesMapping, tsTypes, TsTypes } from '../layerMetadata/decorators/property/tsTypes.decorator';
Expand Down
18 changes: 18 additions & 0 deletions src/models/raster/constants.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
/* eslint-disable @typescript-eslint/naming-convention */
/* eslint-disable @typescript-eslint/no-magic-numbers */
import { zoomLevelToResolutionDeg, zoomLevelToResolutionMeter } from '@map-colonies/mc-utils';

export const RasterProductTypes = {
Orthophoto: 'Orthophoto',
OrthophotoHistory: 'OrthophotoHistory',
OrthophotoBest: 'OrthophotoBest',
RasterMap: 'RasterMap',
RasterMapBest: 'RasterMapBest',
RasterAid: 'RasterAid',
RasterAidBest: 'RasterAidBest',
RasterVector: 'RasterVector',
RasterVectorBest: 'RasterVectorBest',
} as const;

export const RASTER_PRODUCT_TYPES = Object.values(RasterProductTypes);

export const VALIDATIONS = {
boundingBox: {
pattern: '^-?(0|[1-9]\\d*)(\\.\\d*)?,-?(0|[1-9]\\d*)(\\.\\d*)?,-?(0|[1-9]\\d*)(\\.\\d*)?,-?(0|[1-9]\\d*)(\\.\\d*)?$',
Expand Down Expand Up @@ -36,4 +51,7 @@ export const VALIDATIONS = {
sensor: {
pattern: '^(?!\\s).+(?<!\\s)$',
},
polygonPartsEntityName: {
CL-SHLOMIKONCHA marked this conversation as resolved.
Show resolved Hide resolved
pattern: '^[a-z][a-z0-9_]{0,61}[a-z0-9]$',
},
};
1 change: 1 addition & 0 deletions src/models/raster/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './constants';
export type { RasterProductTypes } from './types';

This file was deleted.

3 changes: 1 addition & 2 deletions src/models/raster/ingestion/zod/schemas/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export * from './aggregationLayerMetadata.schema';
export * from './inputFiles.schema';
export * from './metadata.schema';
export * from './partData.schema';
export * from './polygonParts.schema';
93 changes: 92 additions & 1 deletion src/models/raster/ingestion/zod/schemas/metadata.schema.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/no-magic-numbers */
import { z } from 'zod';
import { z, ZodType } from 'zod';
import { MultiPolygon, Polygon } from 'geojson';
import { VALIDATIONS } from '../../../constants';
import { ProductType, Transparency } from '../../../../layerMetadata/enums';

Expand All @@ -25,3 +26,93 @@ export const updateMetadataSchema = z
classification: z.string().regex(new RegExp(VALIDATIONS.classification.pattern)),
})
.describe('updateMetadataSchema');

export const aggregationMetadataSchema = z
.object(
{
footprint: z.custom<Polygon | MultiPolygon>(),
imagingTimeBeginUTC: z.coerce.date({ message: 'Imaging time begin UTC should be a datetime' }),
imagingTimeEndUTC: z.coerce.date({ message: 'Imaging time end UTC should be a datetime' }),
maxHorizontalAccuracyCE90: z
.number({ message: 'Max horizontal accuracy CE90 should be a number' })
.min(VALIDATIONS.horizontalAccuracyCE90.min, {
message: `Max horizontal accuracy CE90 should not be less than ${VALIDATIONS.horizontalAccuracyCE90.min}`,
})
.max(VALIDATIONS.horizontalAccuracyCE90.max, {
message: `Max horizontal accuracy CE90 should not be larger than ${VALIDATIONS.horizontalAccuracyCE90.max}`,
}),
maxResolutionDeg: z
.number({ message: 'Max resolution degree should be a number' })
.min(VALIDATIONS.resolutionDeg.min as number, {
message: `Max resolution degree should not be less than ${VALIDATIONS.resolutionDeg.min as number}`,
})
.max(VALIDATIONS.resolutionDeg.max as number, {
message: `Max resolution degree should not be larger than ${VALIDATIONS.resolutionDeg.max as number}`,
}),
maxResolutionMeter: z
.number({ message: 'Max resolution meter should be a number' })
.min(VALIDATIONS.resolutionMeter.min as number, {
message: `Max resolution meter should not be less than ${VALIDATIONS.resolutionMeter.min as number}`,
})
.max(VALIDATIONS.resolutionMeter.max as number, {
message: `Max resolution meter should not be larger than ${VALIDATIONS.resolutionMeter.max as number}`,
}),
minHorizontalAccuracyCE90: z
.number({ message: 'Min horizontal accuracy CE90 should be a number' })
.min(VALIDATIONS.horizontalAccuracyCE90.min, {
message: `Min horizontal accuracy CE90 should not be less than ${VALIDATIONS.horizontalAccuracyCE90.min}`,
})
.max(VALIDATIONS.horizontalAccuracyCE90.max, {
message: `Min horizontal accuracy CE90 should not be larger than ${VALIDATIONS.horizontalAccuracyCE90.max}`,
}),
minResolutionDeg: z
.number({ message: 'Min resolution degree should be a number' })
.min(VALIDATIONS.resolutionDeg.min as number, {
message: `Min resolution degree should not be less than ${VALIDATIONS.resolutionDeg.min as number}`,
})
.max(VALIDATIONS.resolutionDeg.max as number, {
message: `Min resolution degree should not be larger than ${VALIDATIONS.resolutionDeg.max as number}`,
}),
minResolutionMeter: z
.number({ message: 'Min resolution meter should be a number' })
.min(VALIDATIONS.resolutionMeter.min as number, {
message: `Min resolution meter should not be less than ${VALIDATIONS.resolutionMeter.min as number}`,
})
.max(VALIDATIONS.resolutionMeter.max as number, {
message: `Min resolution meter should not be larger than ${VALIDATIONS.resolutionMeter.max as number}`,
}),
productBoundingBox: z.string({ message: 'Product bounding box should be a string' }).regex(new RegExp(VALIDATIONS.boundingBox.pattern), {
message: 'Product bounding box must be of the shape min_x,min_y,max_x,max_y',
}),
sensors: z
.array(
z.string({ message: 'Sensors should be an array of strings' }).regex(new RegExp(VALIDATIONS.sensor.pattern), {
message: 'Sensors should be an array with items not starting or ending with whitespace characters',
}),
{ message: 'Sensors should be an array' }
)
.min(1, { message: 'Sensors should have an array length of at least 1' }),
},
{ message: 'Layer metadata should be an object' }
)
.strict()
.refine(
(aggregationLayerMetadata) =>
aggregationLayerMetadata.imagingTimeBeginUTC <= aggregationLayerMetadata.imagingTimeEndUTC &&
aggregationLayerMetadata.imagingTimeEndUTC <= new Date(),
{
message: 'Imaging time begin UTC should be less than or equal to imaging time end UTC and both less than or equal to current timestamp',
}
)
.refine((aggregationLayerMetadata) => aggregationLayerMetadata.minHorizontalAccuracyCE90 <= aggregationLayerMetadata.maxHorizontalAccuracyCE90, {
message: 'Min horizontal accuracy CE90 should be less than or equal to max horizontal accuracy CE90',
})
.refine((aggregationLayerMetadata) => aggregationLayerMetadata.minResolutionDeg <= aggregationLayerMetadata.maxResolutionDeg, {
message: 'Min resolution degree should be less than or equal to max resolution degree',
})
.refine((aggregationLayerMetadata) => aggregationLayerMetadata.minResolutionMeter <= aggregationLayerMetadata.maxResolutionMeter, {
message: 'Min resolution meter should be less than or equal to max resolution meter',
})
.describe('aggregationLayerMetadataSchema');

export type AggregationLayerMetadata = z.infer<typeof aggregationMetadataSchema>;
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import type { Polygon } from 'geojson';
import { z } from 'zod';
import { VALIDATIONS } from '../../../constants';
import { RASTER_PRODUCT_TYPES } from '../../../constants';

export const partSchema = z
.object({
Expand Down Expand Up @@ -66,3 +67,19 @@ export const partSchema = z
message: 'Imaging time begin UTC should be less than or equal to imaging time end UTC and both less than or equal to current timestamp',
})
.describe('partSchema');

export const polygonPartsEntityNameSchema = z
.object({
polygonPartsEntityName: z
.string()
.regex(new RegExp(VALIDATIONS.polygonPartsEntityName.pattern), { message: 'Polygon parts entity name should valid entity name' })
.refine(
(value) => {
return RASTER_PRODUCT_TYPES.some((type) => value.endsWith(type.toLowerCase()));
},
{ message: 'Polygon parts entity name should end with one of the valid raster product types' }
),
})
.describe('polygonPartsEntityNameSchema');

export type PolygonPartsEntityName = z.infer<typeof polygonPartsEntityNameSchema>;
3 changes: 3 additions & 0 deletions src/models/raster/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { RasterProductTypes } from './constants';

export type RasterProductTypes = (typeof RasterProductTypes)[keyof typeof RasterProductTypes];