Skip to Content
⚠️Active Development Notice: TimeTiles is under active development. Information may be placeholder content or not up-to-date.

web


web / lib/services/import-configure-service

lib/services/import-configure-service

Service functions for the import configuration workflow.

Extracts Payload-dependent orchestration logic from the configure-import API route into a testable service layer. Also contains pure helper functions for building dataset mappings, field mapping overrides, ID strategies, and geo field detection config used during import configuration.

Functions

buildFieldMappingOverrides()

buildFieldMappingOverrides(fieldMapping): { titlePath?: undefined; descriptionPath?: undefined; locationNamePath?: undefined; timestampPath?: undefined; latitudePath?: undefined; longitudePath?: undefined; locationPath?: undefined; } | { titlePath: string \| null; descriptionPath: string \| null; locationNamePath: string \| null; timestampPath: string \| null; latitudePath: string \| null; longitudePath: string \| null; locationPath: string \| null; }

Parameters

fieldMapping

FieldMapping | undefined

Returns

{ titlePath?: undefined; descriptionPath?: undefined; locationNamePath?: undefined; timestampPath?: undefined; latitudePath?: undefined; longitudePath?: undefined; locationPath?: undefined; } | { titlePath: string \| null; descriptionPath: string \| null; locationNamePath: string \| null; timestampPath: string \| null; latitudePath: string \| null; longitudePath: string \| null; locationPath: string \| null; }


buildIdStrategy()

buildIdStrategy(fieldMapping, deduplicationStrategy): { type: "auto"; duplicateStrategy: "update" \| "version" \| "skip"; externalIdPath?: undefined; } | { type: "external" \| "computed" \| "auto" \| "hybrid"; externalIdPath: string \| null; duplicateStrategy: "update" \| "version" \| "skip"; }

Parameters

fieldMapping

FieldMapping | undefined

deduplicationStrategy

"update" | "version" | "skip"

Returns

{ type: "auto"; duplicateStrategy: "update" \| "version" \| "skip"; externalIdPath?: undefined; } | { type: "external" \| "computed" \| "auto" \| "hybrid"; externalIdPath: string \| null; duplicateStrategy: "update" \| "version" \| "skip"; }


buildGeoFieldDetection()

buildGeoFieldDetection(fieldMapping, geocodingEnabled): object

Parameters

fieldMapping

FieldMapping | undefined

geocodingEnabled

boolean

Returns

object

autoDetect

autoDetect: boolean = geocodingEnabled

latitudePath

latitudePath: string | undefined

longitudePath

longitudePath: string | undefined


buildDatasetMapping()

buildDatasetMapping(sheetMappings, datasetMappingEntries): { mappingType: string; singleDataset: number \| undefined; sheetMappings?: undefined; } | { singleDataset?: undefined; mappingType: string; sheetMappings: [DatasetMappingEntry](../types/import-wizard.md#datasetmappingentry)[]; }

Parameters

sheetMappings

SheetMapping[]

datasetMappingEntries

DatasetMappingEntry[]

Returns

{ mappingType: string; singleDataset: number \| undefined; sheetMappings?: undefined; } | { singleDataset?: undefined; mappingType: string; sheetMappings: [DatasetMappingEntry](../types/import-wizard.md#datasetmappingentry)[]; }


translateSchemaMode()

translateSchemaMode(mode): object

Translate user-friendly schema mode to dataset schemaConfig fields.

Parameters

mode

"strict" | "additive" | "flexible"

Returns

object

locked

locked: boolean = true

autoGrow

autoGrow: boolean = false

autoApproveNonBreaking

autoApproveNonBreaking: boolean = false


processDataset()

processDataset(payload, req, sheetMapping, fieldMapping, catalogId, deduplicationStrategy, geocodingEnabled, transforms?): Promise<number>

Parameters

payload

BasePayload

req

NextRequest

sheetMapping

SheetMapping

fieldMapping

FieldMapping | undefined

catalogId

number

deduplicationStrategy

"update" | "version" | "skip"

geocodingEnabled

boolean

transforms?

ImportTransform[]

Returns

Promise<number>


processSheetMappings()

processSheetMappings(payload, req, sheetMappings, fieldMappings, catalogId, deduplicationStrategy, geocodingEnabled, transformsBySheet?): Promise<{ datasetIdMap: Map\<number, number\>; datasetMappingEntries: [DatasetMappingEntry](../types/import-wizard.md#datasetmappingentry)[]; }>

Process all sheet mappings and return dataset mapping entries. Bug 28 fix: process sequentially instead of in parallel to prevent race conditions when multiple sheets target the same dataset.

Parameters

payload

BasePayload

req

NextRequest

sheetMappings

SheetMapping[]

fieldMappings

FieldMapping[]

catalogId

number

deduplicationStrategy

"update" | "version" | "skip"

geocodingEnabled

boolean

transformsBySheet?

object[]

Returns

Promise<{ datasetIdMap: Map\<number, number\>; datasetMappingEntries: [DatasetMappingEntry](../types/import-wizard.md#datasetmappingentry)[]; }>


createScheduledImport()

createScheduledImport(payload, scheduleConfig, catalogId, datasetMappingEntries, user, importFileId, previewMeta): Promise<number | null>

Create scheduled import from wizard configuration. Checks the active-schedules quota before creation to prevent bypass (Bug 15).

Parameters

payload

BasePayload

scheduleConfig

CreateScheduleConfig

catalogId

number

datasetMappingEntries

DatasetMappingEntry[]

user

User

importFileId

number

previewMeta

PreviewMetadata

Returns

Promise<number | null>


getOrCreateCatalog()

getOrCreateCatalog(payload, req, catalogId, newCatalogName, user): Promise<number | "forbidden" | null>

Create catalog if needed, verifying ownership for existing catalogs. Returns the catalog ID, null if name is missing, or “forbidden” if access denied.

Parameters

payload

BasePayload

req

NextRequest

catalogId

number | "new"

newCatalogName

string | undefined

user

User

Returns

Promise<number | "forbidden" | null>


createImportFileRecord()

createImportFileRecord(payload, user, previewMeta, body, finalCatalogId, datasetIdMap, datasetMappingEntries): Promise<ImportFile>

Create the import file record from preview metadata and wizard configuration.

Parameters

payload

BasePayload

user

User

previewMeta

PreviewMetadata

body

ConfigureImportRequest

finalCatalogId

number

datasetIdMap

Map<number, number>

datasetMappingEntries

DatasetMappingEntry[]

Returns

Promise<ImportFile>


rethrowQuotaError()

rethrowQuotaError(error): never

Convert QuotaExceededError to AppError so the framework handles it correctly. Bug 15: surface quota-exceeded as 429 rather than 500.

Parameters

error

unknown

Returns

never

Last updated on