Released foundation and later current source
Release v0.6.2 publicly introduced the CSV import foundation for customers.person through the sync_excel provider. The field, scoping, storage, and row behavior below was checked in the later develop revision 01911d00e28f44cf484d0b1d04860dcfef5370bf dated 11 July 2026. Those details are not inferred back into the tag.
CSV export removes workbook semantics
Formulas become exported values or export problems, formatting and merged cells disappear, and multiple sheets must be separated. The importer detects comma or semicolon delimiters, strips a UTF-8 byte order mark, normalizes line endings, and treats the first non-empty row as headers.
Identity determines repeat-import risk
A stable source record ID is the primary matching path. Email is secondary and needs a uniqueness and mutability review. Custom matching is an escalation path. A mapping suggestion or valid interface state does not prove that source data is unique.
For an existing person, the current adapter updates only non-empty values. A blank cell is not a safe clear instruction. A new person needs a usable name. An empty row is skipped, and a primary address is created or updated only when address line 1 is present.
The uploaded file is persisted through attachments
The product stores the file in a private attachment partition and records preview metadata, headers, five sample rows, and row count within tenant and organization scope. The reviewed code does not establish a universal automatic deletion period. The project must decide lawful basis, minimization, access, encryption, retention, deletion, backups, logs, support access, and incident handling.
Supplier offers do not define product scope
Independent suppliers may offer sample review, multi-object migration, or zero-downtime cutover. Those are terms of their services. They are not evidence of the first party module and are not promises from this site. Scope here comes from the release, current source, and evidence from the actual project.
Evidence boundary
Release, current source, and review date
- Latest verified public tag
- v0.6.5 latest verified tag; v0.6.2 importer baseline
- Current source revision
01911d00e28f44cf484d0b1d04860dcfef5370bf- Reviewed
Release v0.6.2 publicly introduced a CSV import foundation for customers.person. The exact fields and behavior below were verified in later current source at the reviewed revision, 1,202 commits after the latest local tag v0.6.5. Current source is not presented as a tagged release.
File and workbook boundary
State describes the evidence boundary, not a promised outcome. Every row needs a fresh check for the actual application and enabled modules.
Open: File and workbook boundary15 items
| Input characteristic | Reviewed state | Current behavior | Preparation decision | Exact evidence |
|---|---|---|---|---|
| .xlsx workbook | not supported natively | The upload route accepts CSV by name or MIME signal, not workbook semantics. | Preserve the original and export one deliberate sheet to UTF-8 CSV. | api/upload/route.ts |
| .xls workbook | not supported natively | No binary Excel parser is present in the reviewed module. | Open safely in a controlled tool and export one sheet to UTF-8 CSV. | api/upload/route.ts |
| .csv file | supported foundation | Text is decoded as UTF-8 and parsed using the first meaningful row as headers. | Confirm encoding, delimiter, row grain, headers, and one entity target. | lib/parser.ts |
| Comma-separated CSV | supported foundation | Delimiter detection compares comma and semicolon field counts in up to five non-empty lines. | Inspect headers and quoted values in the five-row preview. | lib/parser.ts |
| Semicolon-separated CSV | supported foundation | Semicolon is selected only when its score is greater than the comma score. | Use a deliberate separator and verify Polish text and decimal conventions. | lib/parser.ts |
| UTF-8 and UTF-8 BOM | supported foundation | Buffer decoding uses UTF-8 and a leading BOM is stripped. | Export as UTF-8 and inspect Polish characters before any run. | lib/parser.ts |
| Multiple sheets | preparation required | CSV has no sheet model and the importer reads one flat table. | Choose one person sheet and plan other objects separately. | lib/parser.ts |
| Formulas | lost or project-specific | The importer receives exported cell text, not formula logic or dependencies. | Freeze approved values and record the export method and time. | lib/parser.ts |
| Formatting and merged cells | lost | CSV parsing has no style, merged-cell, width, color, or comment model. | Turn visual meaning into explicit columns before export. | lib/parser.ts |
| Blank headers | normalized with risk | A blank header becomes Column N, which does not explain business meaning. | Name every included column and stop on unexplained generated headers. | lib/parser.ts |
| Duplicate headers | not safely evidenced | Rows become objects keyed by header, so a repeated name can overwrite an earlier value. | Make every header unique before upload. | lib/parser.ts |
| Blank rows | ignored or skipped | Meaningless parser rows are removed; an empty imported object is also reported as skipped. | Remove them and reconcile the parser total against source data rows. | lib/parser.ts; lib/adapters/customers.ts |
| Quoted delimiters and quotes | supported foundation | Quoted delimiters and doubled quote characters are handled by the current parser. | Include them in the representative trial and inspect the preview. | lib/parser.ts |
| CRLF, LF, and CR line endings | supported foundation | Line endings are normalized to LF before parsing. | Still compare row counts because quoted line breaks need representative testing. | lib/parser.ts |
| Very large files | project-specific limit | The attachment upload limit applies, parsing loads the buffer, and no universal safe row count is established. | Measure file size, memory, duration, worker behavior, and batch recovery in the target environment. | api/upload/route.ts; lib/parser.ts |
Current import support matrix
Open: Current import support matrix4 items
| Target | Create or update | Identity role | Required condition | Transformation caveat | Data-loss risk | Evidence | Revision | Custom work |
|---|---|---|---|---|---|---|---|---|
| customers.person core fields | Create and non-empty update | External ID primary; email secondary | One concrete organization and usable person name for create | Phone and names use current adapter normalization | Blank does not prove clear; mutable identity can duplicate | validators.ts; customers.ts | 01911d00e28f | Only for source cleanup, unsupported semantics, or custom match |
| Primary address fields | Create or update first primary address | Uses matched person identity | address.addressLine1 must be non-empty | Only mapped, non-empty values are applied | No line 1 means no address action; replacement semantics need trial | target-options.ts; customers.ts | 01911d00e28f | Needed for multiple addresses or other address policy |
| Eligible people custom fields | Create or update against current definition | Not a safe identity by default | Active definition for customer entity or person profile | Boolean, integer, number, date, and text coercion is definition-dependent | Invalid typed value fails the row; relation and dictionary behavior is not generalized | target-options.ts; customers.ts | 01911d00e28f | Project-specific definitions and tests are required |
| Companies, products, prices, orders, invoices, deals, activities, messages, attachments, users, roles, permissions, history, arbitrary entities | Not supported by this adapter | None | Separate migration inventory and approved method | No transformation contract exists in sync_excel | Attempting to flatten objects can lose relationships, history, files, and authority | validators.ts; supportedEntities | 01911d00e28f | Yes: another adapter, API, script, or migration workstream |
Generated current target-field catalogue
Open: Generated current target-field catalogue23 items
| Group | Mapping key | Current label | Suggested aliases | Kind | Identity role | Create or update caveat | Pinned evidence |
|---|---|---|---|---|---|---|---|
| person | person.externalId | External ID | external id, record id, lead id | external_id | primary | Stored as external mapping after create or update. | Pinned source |
| person | person.firstName | First name | first name, firstname, given name | core | not identity | Name derivation can build create values; a new person still needs a usable name. | Pinned source |
| person | person.lastName | Last name | last name, lastname, surname, family name | core | not identity | Name derivation can build create values; a new person still needs a usable name. | Pinned source |
| person | person.displayName | Display name | display name, lead name, full name, name | core | not identity | Name derivation can build create values; a new person still needs a usable name. | Pinned source |
| person | person.primaryEmail | Primary email | email, primary email, email address | core | secondary | Only a non-empty mapped value is applied on update. | Pinned source |
| person | person.primaryPhone | Primary phone | phone, primary phone, mobile, mobile phone, telephone | core | not identity | Only a non-empty mapped value is applied on update. | Pinned source |
| person | person.jobTitle | Job title | job title, title, position | core | not identity | Only a non-empty mapped value is applied on update. | Pinned source |
| person | person.status | Status | status, lead status | core | not identity | Only a non-empty mapped value is applied on update. | Pinned source |
| person | person.source | Source | source, lead source | core | not identity | Only a non-empty mapped value is applied on update. | Pinned source |
| person | person.description | Description | description, notes, comment | core | not identity | Only a non-empty mapped value is applied on update. | Pinned source |
| primary address | address.name | Address label | address label, address name, label | core | not identity | Address action requires non-empty address.addressLine1; only non-empty values update. | Pinned source |
| primary address | address.purpose | Address purpose | address purpose, address type | core | not identity | Address action requires non-empty address.addressLine1; only non-empty values update. | Pinned source |
| primary address | address.companyName | Address company | address company, address company name | core | not identity | Address action requires non-empty address.addressLine1; only non-empty values update. | Pinned source |
| primary address | address.addressLine1 | Address line 1 | address line 1, street address, street, street 1 | core | not identity | Address action requires non-empty address.addressLine1; only non-empty values update. | Pinned source |
| primary address | address.addressLine2 | Address line 2 | address line 2, street 2 | core | not identity | Address action requires non-empty address.addressLine1; only non-empty values update. | Pinned source |
| primary address | address.buildingNumber | Building number | building number, building no, house number | core | not identity | Address action requires non-empty address.addressLine1; only non-empty values update. | Pinned source |
| primary address | address.flatNumber | Flat number | flat number, apartment number, unit number | core | not identity | Address action requires non-empty address.addressLine1; only non-empty values update. | Pinned source |
| primary address | address.city | City | city, town | core | not identity | Address action requires non-empty address.addressLine1; only non-empty values update. | Pinned source |
| primary address | address.region | Region / State | region, state, province | core | not identity | Address action requires non-empty address.addressLine1; only non-empty values update. | Pinned source |
| primary address | address.postalCode | Postal code | postal code, zip code, postcode | core | not identity | Address action requires non-empty address.addressLine1; only non-empty values update. | Pinned source |
| primary address | address.country | Country | country | core | not identity | Address action requires non-empty address.addressLine1; only non-empty values update. | Pinned source |
| primary address | address.latitude | Latitude | latitude, lat | core | not identity | Address action requires non-empty address.addressLine1; only non-empty values update. | Pinned source |
| primary address | address.longitude | Longitude | longitude, lng, lon | core | not identity | Address action requires non-empty address.addressLine1; only non-empty values update. | Pinned source |
Workbook preparation and identity decision path
Preserve an unchanged original workbook under the approved information classification and access policy.
Choose exactly one source sheet and one row grain: one row must represent one person record.
Assign a source owner who can explain every column, formula, code, blank, and exception.
Define a stable immutable source record ID. Prefer it for repeat imports and document its system of origin.
Profile duplicate IDs and duplicate or mutable email addresses. Stop until collisions have an approved rule.
Normalize names, phone numbers, countries, dates, enumerations, and whitespace outside the importer, with a reversible record of the rule.
Decide empty versus clear semantics. The current adapter ignores empty values on update, so a blank is not a delete instruction.
Separate companies, products, prices, orders, invoices, history, attachments, users, permissions, and other unsupported objects into their own workstreams.
Classify and minimize personal data. Approve lawful basis, environment, access, storage, retention, deletion, backups, logs, support access, and incident handling.
Create a representative, lawfully controlled trial extract that includes expected formats and failure cases without using this website to hold row data.
Export the chosen sheet as UTF-8 CSV with a deliberate comma or semicolon delimiter. Reopen it as plain text and inspect headers and Polish characters.
Record the workbook version, sheet, CSV version, source data-row count, file hash, export method, timestamp, owner, and approval.
Select one concrete organization, upload the CSV, inspect the five-row preview and total, and review every mapped and unmapped header.
Choose external ID when stable. Use email only after uniqueness and mutability review. Escalate custom matching rather than treating it as safe deduplication.
Run the approved background trial, observe created, updated, skipped, and failed counters, inspect failures, reconcile business samples, and decide whether a corrected repeat import is safe.
Three-pass trial protocol
Open: Three-pass trial protocol3 items
| Pass | Owner | Input version | Expected outcomes | Sampling and evidence | Stop condition | Cleanup or retention | Approval boundary |
|---|---|---|---|---|---|---|---|
| 1. Header-only design review | Data owner and migration lead | Approved schema and mapping version | Every included header classified; no create, update, skip, or fail run | Mapping ledger, unsupported-object list, identity decision | Unexplained column, unstable identity, unknown blank rule, or privacy approval missing | Retain schema decisions only; no row data on this site | Data owner approves trial design, not production import |
| 2. Representative controlled trial | Migration operator and business reviewer | Hashed trial CSV and mapping version | Predicted created, updated, skipped, and failed counts recorded before run | All failures plus risk-based samples of names, identity, address, and custom fields | Count mismatch, duplicate candidate, unexpected write, unresolved skip or fail, or storage problem | Apply the approved retention and cleanup action to upload, logs, evidence, and test records | Business and data owners accept only this trial evidence |
| 3. Repeat-import and idempotency check | Migration lead and application owner | Same controlled input or approved corrected revision | Expected update, skip, and fail behavior with zero unexplained new people | Identity mapping evidence, duplicate search, before and after counts, accepted variances | Unexpected create, identity drift, partial-failure ambiguity, or no rollback owner | Execute the same approved retention action and record remaining artifacts | Authorized sponsor may approve a next migration gate only after reconciliation |
Current product flow and program boundaries
At the reviewed version, sync_excel.view and sync_excel.run are distinct features. The operator enables or opens the integration, selects one concrete organization, uploads CSV, inspects a five-row preview and the total row count, reviews every mapping, chooses identity, and starts a background run. The operator then compares created, updated, skipped, and failed counters, investigates failures, and decides whether a corrected repeat import is safe only after reconciliation. An overlapping run for the same entity type and scope is rejected.
These mechanics do not replace migration inventory, source-of-record decisions, cross-object relationships, users and permissions, history and attachments, a trial environment, business reconciliation, freeze or incremental sync, cutover, rollback, legacy-system decommissioning, or retention.
- Migration program, relationships, history, trials, and cutover
- Source-of-record, field, and transformation decisions
- Environments, delivery ownership, and business acceptance
- Incremental synchronization and integration reconciliation
- Personal data, access, retention, and incident response
- Cutover, rollback, stabilization, and decommissioning
Open: Local-only reconciliation sheet
Local planning tool
Local-only reconciliation sheet
Enter counts, statuses, abstract role labels, and evidence references only. Do not enter or upload files, row values, names, emails, phones, addresses, credentials, personal data, secrets, production identifiers, or tokenized links. This planning state stays in this browser; reset, text export, JSON export, and print are local. A completed engine run is transport evidence, not proof of business completeness.
Privacy: this page does not submit worksheet content, place it in the URL, or store it in cookies.
Hypothetical examples
Open: Synthetic examples2 items
Synthetic example
Contact export with stable CRM IDs
- Accountable role
- Data owner role A
- Input version or hash reference
- Synthetic file hash reference A
- Mapping version
- Mapping draft A
- Organization scope label
- One test organization
- Identity strategy status
- Stable fictional source IDs selected
- Source data rows
- 120
- Parser total
- 120
Synthetic example
Workbook with names, emails, companies, orders, and history tabs
- Accountable role
- Migration sponsor role B
- Input version or hash reference
- Synthetic workbook inventory B
- Mapping version
- Not approved
- Organization scope label
- Undecided
- Identity strategy status
- Names and mutable emails only; stop
- Source data rows
- People tab count only
- Parser total
- Not run
Evidence to reconcile before approval
Open: Evidence to reconcile before approval10 items
- Source rows equal the intended business grain
- Parser total is explained against source data rows
- Processed equals created plus updated plus skipped plus failed under the reviewed counter contract
- Every skipped and failed row has an owner and disposition
- Duplicate candidates and repeat-import creates are resolved
- Expected addresses and custom-field outcomes are sampled and reconciled
- Accepted variances are explicit, dated, and approved
- Upload, preview, run, logs, test records, and evidence follow the approved retention action
- Comma and semicolon CSV, UTF-8 Polish headers, quotes, blank and duplicate headers, blank rows, and line endings were tested
- External ID, email, missing name, custom matching, all-organizations denial, overlap, storage failure, no JavaScript, reset, print, and export paths were reviewed
Stop and escalation conditions
- The native workbook has not been converted deliberately to UTF-8 CSV, or workbook semantics still carry business meaning.
- The target includes an unsupported object, cross-object relationship, history, attachment, user, role, or permission.
- There is no stable identity, emails are duplicate or mutable without an approved rule, or custom matching is not independently designed.
- A new row has no usable name, the blank-versus-clear rule is ambiguous, or a custom-field type is unknown.
- All organizations is selected, a column is unexplained, personal-data handling is not approved, or no concrete owner can authorize the environment.
- Source and parser counts differ without explanation, skipped or failed rows remain unresolved, or sampled business values do not reconcile.
- No backup, rollback, cleanup, retention, cutover, support, or incident owner exists.
- A repeated import creates unexpected people, identity mappings drift, or partial-failure recovery is not understood.
- The project treats importer completion as proof of source-of-record choice, relationship preservation, business completeness, cutover readiness, rollback, decommissioning, or retention compliance.
Selected verification sources
Links are contextual evidence. They do not replace review of the actual application.
Method, assumptions and limitations
Reviewed 14 July 2026. Product facts were checked against both the public code at the cited repository revision and official documentation. Where documentation and code differ, this guide describes behavior supported by code. Interpretations and recommendations concern implementation work, not product guarantees.
This material is not a quote, audit, certification, or legal, tax, or accounting advice. Edition, enabled modules, configuration, custom code, infrastructure, data, third-party providers, and operating practices affect the outcome.
Primary source collections: code repository, documentation, public releases.