Cross-cutting · CSV import engine
The shared engine behind every bulk import in the product: upload a CSV, auto-map its headers to model attributes, choose the separator, the match key, the date format, consent defaults and channels, preview and import — with the file stored server-side and the job queued as a
loadrecord.
| Area | Cross-cutting |
| Routes | crm.users.import · crm.users.import-children · crm.commerces.import · configuration.influence-zones.import · intranet.flows.import |
| Centre modules | always available |
| Staff levels | root · admin |
| Models | load · load-common |
| UI label | import-csv.column-database |
| Coverage | 4 use cases · 1 happy · 8 failure |
Known issues (1)
How it works
Two implementations coexist: the older import-csv component (modal-based, fixed ; delimiter, 120 lines) and the newer nf-import (606 lines, full page, configurable separator and primary key, preview table, template download, canImportChildren/canRemoveUserTypes affordances and a pre-flight error summary). Both drive the same load model, whose three validations are the real contract: no duplicate column mappings, a date format whenever a date column is mapped, and at least one channel for user imports. parseCSV parses and uploads in parallel (Promise.all), so the mapping table and the stored file are produced in one step. update: true switches between insert-only and update-and-insert.
Use cases
Why someone opens this (4)
- Migrating a legacy customer or store database during onboarding.
- Periodic bulk updates from a POS, HR or counting system.
- Loading reference data such as postal-code-to-zone mappings.
- Giving a non-technical user a safe, previewable alternative to an API integration.
Path map
flowchart LR F(["CSV import engine"]):::feat F --> H1["Template import with preview"]:::ok F -.-> X1["Duplicate column mapping"]:::bad F -.-> X2["Date column without a format"]:::bad F -.-> X3["User import without channels"]:::bad F -.-> X4["Pre-flight summary"]:::bad F -.-> X5["Upload rejected"]:::bad F -.-> X6["Server-side row errors"]:::bad F -.-> X7["Parse failure leaves a stuck spinner"]:::bad F -.-> X8["Wrong separator chosen"]:::bad classDef feat fill:#8c5a3c,stroke:#8c5a3c,color:#ffffff,font-weight:bold classDef ok fill:#e3f1ea,stroke:#0d6b42,color:#0d4a2e classDef bad fill:#f7e6e2,stroke:#9a2d1c,color:#6e1f13
Happy paths
Template import with preview
- User downloads the entity’s example CSV (which varies by centre configuration) and fills it.
- Uploads the file; it is parsed and stored in parallel.
- Headers matching attribute names are mapped automatically; the rest are mapped by hand.
- Separator, match key, date format, consents and channels are set.
- The preview table shows how rows will be interpreted.
load.validate()passes,load.save()queues the job and the success state is reported.
Failure paths
Duplicate column mapping
Cause — Two CSV columns mapped to the same attribute.
What happens —
error.load.repeated-fields(‘Please select a single database field for each CSV column’);import-csvscrolls the modal to the top to reveal it.
Date column without a format
Cause —
register_dateorbdatemapped with noformatDate.What happens —
error.load.format-date.required/import-csv.errors.load.format-date.required.
User import without channels
Cause —
model === 'user'andcommons.channelsempty.What happens —
error.load.channels.required/import-csv.errors.load.channels.required.
Pre-flight summary
Cause —
nf-import._validateSelectionsAndShowErrorsfinds any required selection missing.What happens —
import-csv.errors.load.required-selectionsas a banner — note this string is in Portuguese while its siblings are English.
Upload rejected
Cause — Disallowed file type or oversized file.
What happens —
error.file.type.not_allowed,error.file.oversize,error.file.not_allowed.
Server-side row errors
Cause — Rows rejected during processing.
What happens —
informative-message.import-csv.error.title+informative-message.import-csv.errorlist them.nf-importalso readserror?.errors?.[0]?.statusto classify the failure.
Parse failure leaves a stuck spinner
Cause — Unparseable file in the older
import-csvcomponent.What happens —
parseCSVisasyncwith no try/catch there, soisLoadingstays true.nf-importhandles this better with explicit try/catch blocks.
Wrong separator chosen
Cause — File uses
,but;is selected (or vice versa).What happens — Configurable in
nf-import(onChangeSeparator); hard-coded to;inimport-csv, where a comma-separated file parses as a single column.
QA checklist
Tick these off while regression-testing this feature. The boxes are plain Markdown, so progress is visible in git diffs.
- ✅ Template import with preview
- ⛔ Duplicate column mapping
- ⛔ Date column without a format
- ⛔ User import without channels
- ⛔ Pre-flight summary
- ⛔ Upload rejected
- ⛔ Server-side row errors
- ⛔ Parse failure leaves a stuck spinner
- ⛔ Wrong separator chosen
Implementation
app/components/nf-import.jsapp/components/import-csv.jsapp/models/load.jsapp/models/load-common.jsapp/services/csv.jsapp/services/api-files.jsapp/enums/csv-examples.js
Translation keys (20)
Key English import-csv.column-csvCSV Field import-csv.column-databaseDatabase field import-csv.separation-options.commaSeparator option comma: (,) import-csv.separation-options.semiconSeparator option semicon: (;) import-csv.formats-date.dd-mm-yyyyDD/MM/YYYY import-csv.formats-date.mm-dd-yyyyMM/DD/YYYY import-csv.formats-date.yyy-mm-ddYYYY-MM-DD import-csv.update-options.only-insertOnly insert new data without updating existing data import-csv.update-options.update-insertUpdate existing data and insert new data error.load.repeated-fieldsThere are fields have been selected more than once. Please select a single database field for each CSV column. error.load.format-date.requiredFormat date is required error.load.channels.requiredChannels are required import-csv.errors.load.required-selectionsAtenção! Faltam campos obrigatórios. Revise-os antes de importar. import-csv.errors.load.channels.requiredChannels are required, please select at least one. import-csv.errors.load.format-date.requiredFormat date is required, please select one. informative-message.import-csv.error.titleAn error ocurred informative-message.import-csv.errorThe following errors have occurred error.file.type.not_allowedFile type not allowed error.file.oversizeFile exceeds the maximum file size error.file.not_allowedFile not allowed
Related
- Same area — Data export engine (email delivery) · Filter & segment builder component · File upload, gallery & image modal · Multi-language content authoring · Realtime updates (Pusher) · Role & module permission layer · Error presentation & API error mapping · Product analytics & error monitoring
- Shares data with — Customer CSV import · Children CSV import · Store CSV import · Footfall (flows) & Yardi upload · Influence zones
Generated from doc/feature-inventory.json · id xc-csv-import-engine · commit 276788ca6