17 KiB
17 KiB
CSV Import Mapping
This document maps supported setup CSV columns to target fields and reference resolvers.
Common resolver rules:
organization_coderesolves to the setup organization by wizard code, organization slug, or import context alias.*_emailresolves tousers.email.branch_coderesolves toms_optionswherecategory = crm_branch.product_type_coderesolves toms_optionswherecategory = crm_product_type.- Master option values resolve by category and code unless a target field explicitly stores plain text.
- All imported rows are organization-scoped unless noted otherwise.
organizations.csv
| CSV Column | Target Field | Transform | Validation | Required | Reference Resolver | Fallback | Notes |
|---|---|---|---|---|---|---|---|
organization_code |
setup alias / metadata | trim uppercase | unique in import batch | yes | none | none | Not currently a DB column; used by setup import context. |
organization_name |
organizations.name |
trim | non-empty | yes | none | none | |
slug |
organizations.slug |
trim lowercase | unique | yes | organizations.slug duplicate check |
generated from name only in wizard mode | |
created_by_email |
organizations.created_by |
lowercase email | user exists | yes | users.email -> id |
current setup actor | |
plan |
organizations.plan |
trim lowercase | known plan string | no | none | enterprise for setup-created org |
|
logo_url |
organizations.image_url |
trim | URL or relative path | no | none | null |
users.csv
| CSV Column | Target Field | Transform | Validation | Required | Reference Resolver | Fallback | Notes |
|---|---|---|---|---|---|---|---|
email |
users.email |
trim lowercase | email format, unique | yes | duplicate by email | none | Upsert key. |
name |
users.name |
trim | non-empty | yes | none | email local part | |
system_role |
users.system_role |
trim lowercase | super_admin,user |
yes | none | user |
|
password |
users.password_hash |
bcrypt hash | required for new credentials user | no | none | generated invite flow later | Do not store raw password. |
active_organization_code |
users.active_organization_id |
resolve | org exists | no | organization resolver | null | |
image_url |
users.image |
trim | URL optional | no | none | null | |
reset_password |
import behavior | boolean | true/false | no | none | false | Allows password update for existing users. |
memberships.csv
| CSV Column | Target Field | Transform | Validation | Required | Reference Resolver | Fallback | Notes |
|---|---|---|---|---|---|---|---|
organization_code |
memberships.organization_id |
resolve | org exists | yes | organization resolver | setup org | |
user_email |
memberships.user_id |
lowercase | user exists | yes | users.email |
none | |
membership_role |
memberships.role |
lowercase | admin,user |
yes | none | user |
|
business_role |
memberships.business_role |
lowercase | known CRM fallback role | yes | role definition code | sales_support |
Compatibility fallback only. |
permissions |
memberships.permissions |
pipe split | known permission codes | no | src/lib/auth/rbac.ts |
default permissions | |
branch_scope_codes |
memberships.branch_scope_ids |
pipe split resolve | branch options exist | no | crm_branch options |
empty array | Compatibility scope only. |
product_type_scope_codes |
memberships.product_type_scope_ids |
pipe split resolve | product type options exist | no | crm_product_type options |
empty array | Compatibility scope only. |
crm-role-assignments.csv
| CSV Column | Target Field | Transform | Validation | Required | Reference Resolver | Fallback | Notes |
|---|---|---|---|---|---|---|---|
organization_code |
organization_id |
resolve | org exists | yes | organization resolver | setup org | |
user_email |
user_id |
lowercase | user + membership exist | yes | user resolver | none | |
crm_role_code |
role_profile_id |
lowercase | role profile exists | yes | crm_role_profiles.code |
none | |
is_primary |
is_primary |
boolean | true/false | yes | none | false | One primary per user warning/enforcement. |
branch_scope_mode |
branch_scope_mode |
lowercase | all,selected,none,inherit |
yes | none | inherit |
|
branch_codes |
branch_scope_ids |
pipe split resolve | required when mode selected | no | crm_branch options |
empty array | |
product_type_scope_mode |
product_type_scope_mode |
lowercase | all,selected,none,inherit |
yes | none | inherit |
|
product_type_codes |
product_type_scope_ids |
pipe split resolve | required when mode selected | no | crm_product_type options |
empty array | |
is_active |
is_active |
boolean | true/false | no | none | true |
master-options.csv
| CSV Column | Target Field | Transform | Validation | Required | Reference Resolver | Fallback | Notes |
|---|---|---|---|---|---|---|---|
organization_code |
organization_id |
resolve | org exists | yes | organization resolver | setup org | |
category |
category |
trim lowercase | non-empty | yes | none | none | |
code |
code |
trim | non-empty unique per category | yes | duplicate check | none | |
label |
label |
trim | non-empty | yes | none | none | |
value |
value |
trim | optional | no | none | same as code | |
parent_category |
parent lookup | trim | parent requires parent_code | no | ms_options.category |
null | |
parent_code |
parent_id |
resolve | parent exists | no | ms_options.category+code |
null | |
sort_order |
sort_order |
integer | >= 0 | no | none | 0 | |
is_active |
is_active |
boolean | true/false | no | none | true | |
metadata_json |
metadata |
JSON parse | valid object | no | none | null |
branches.csv
Maps to ms_options with fixed category = crm_branch.
| CSV Column | Target Field | Transform | Validation | Required | Reference Resolver | Fallback | Notes |
|---|---|---|---|---|---|---|---|
organization_code |
organization_id |
resolve | org exists | yes | organization resolver | setup org | |
branch_code |
code, value |
trim lowercase snake_case | unique per org | yes | duplicate check | none | |
branch_name |
label |
trim | non-empty | yes | none | none | |
prefix |
metadata.prefix |
trim uppercase | optional | no | none | first letters of code | Used by sequence suggestions only. |
address |
metadata.address |
trim | optional | no | none | null | |
tax_id |
metadata.taxId |
trim | optional | no | none | null | |
phone |
metadata.phone |
trim | optional | no | none | null | |
email |
metadata.email |
lowercase | email optional | no | none | null | |
sort_order |
sort_order |
integer | >= 0 | no | none | 0 | |
is_active |
is_active |
boolean | true/false | no | none | true |
product-types.csv
Maps to ms_options with fixed category = crm_product_type.
| CSV Column | Target Field | Transform | Validation | Required | Reference Resolver | Fallback | Notes |
|---|---|---|---|---|---|---|---|
organization_code |
organization_id |
resolve | org exists | yes | organization resolver | setup org | |
product_type_code |
code, value |
lowercase snake_case | unique per org | yes | duplicate check | none | |
product_type_name |
label |
trim | non-empty | yes | none | none | |
document_prefix |
metadata.documentPrefix |
uppercase | optional | no | none | derived from code | Used for sequence suggestion. |
sort_order |
sort_order |
integer | >= 0 | no | none | 0 | |
is_active |
is_active |
boolean | true/false | no | none | true | |
metadata_json |
metadata merge |
JSON parse | object | no | none | null | Merged after documentPrefix. |
document-sequences.csv
| CSV Column | Target Field | Transform | Validation | Required | Reference Resolver | Fallback | Notes |
|---|---|---|---|---|---|---|---|
organization_code |
organization_id |
resolve | org exists | yes | organization resolver | setup org | |
branch_code |
branch_id |
resolve | option exists when provided | no | crm_branch option |
empty string | Empty string means generic branch scope. |
product_type_code |
product_type |
normalize | option exists or all |
no | crm_product_type option/code |
all |
Store normalized code, not option id. |
document_type |
document_type |
lowercase | supported by sequence foundation | yes | none | none | |
prefix |
prefix |
trim | non-empty | yes | none | none | |
period |
period |
trim | matches active period format | yes | none | generated current YYMM later | |
current_number |
current_number |
integer | >= 0 | no | none | 0 | |
padding_length |
padding_length |
integer | 1-12 | no | none | 3 | |
format |
format |
trim | contains {running} |
no | none | {prefix}{period}-{running} |
|
reset_policy |
reset_policy |
lowercase | known reset policy | no | none | period |
|
is_active |
is_active |
boolean | true/false | no | none | true |
approval-workflows.csv
| CSV Column | Target Field | Transform | Validation | Required | Reference Resolver | Fallback | Notes |
|---|---|---|---|---|---|---|---|
organization_code |
organization_id |
resolve | org exists | yes | organization resolver | setup org | |
workflow_code |
code |
lowercase snake_case | unique per org | yes | duplicate check | none | |
workflow_name |
name |
trim | non-empty | yes | none | none | |
entity_type |
entity_type |
lowercase | quotation initially |
yes | none | quotation |
|
description |
description |
trim | optional | no | none | null | |
is_system |
is_system |
boolean | true/false | no | none | false | |
is_active |
is_active |
boolean | true/false | no | none | true |
approval-steps.csv
| CSV Column | Target Field | Transform | Validation | Required | Reference Resolver | Fallback | Notes |
|---|---|---|---|---|---|---|---|
organization_code |
organization_id |
resolve | org exists | yes | organization resolver | setup org | |
workflow_code |
workflow_id |
resolve | workflow exists | yes | approval workflow | none | |
step_number |
step_number |
integer | > 0 | yes | none | none | |
role_code |
role_code |
lowercase | role code known | yes | role profile optional check | none | |
role_name |
role_name |
trim | non-empty | yes | none | label from role profile | |
approval_mode |
approval_mode |
lowercase | known mode | no | none | sequential |
|
is_required |
is_required |
boolean | true/false | no | none | true | |
sla_hours |
sla_hours |
integer | >= 0 | no | none | 24 | |
calendar_mode |
calendar_mode |
lowercase | known mode | no | none | calendar_days |
|
timeout_action |
timeout_action |
lowercase | known action | no | none | none |
approval-matrix.csv
| CSV Column | Target Field | Transform | Validation | Required | Reference Resolver | Fallback | Notes |
|---|---|---|---|---|---|---|---|
organization_code |
organization_id |
resolve | org exists | yes | organization resolver | setup org | |
entity_type |
entity_type |
lowercase | quotation initially |
yes | none | quotation | |
workflow_code |
workflow_id |
resolve | workflow exists | yes | approval workflow | none | |
branch_code |
branch_id |
resolve | optional branch exists | no | branch option | null | Null means any branch. |
product_type_code |
product_type |
normalize | optional product type exists | no | product type option/code | null | |
min_amount |
min_amount |
decimal | <= max when both exist | no | none | null | |
max_amount |
max_amount |
decimal | >= min when both exist | no | none | null | |
currency |
currency |
uppercase | currency option exists | no | crm_currency |
null | |
priority |
priority |
integer | >= 0 | yes | none | 100 | |
is_default |
is_default |
boolean | true/false | yes | none | false | |
is_active |
is_active |
boolean | true/false | no | none | true | |
description |
description |
trim | optional | no | none | null |
CRM Business CSVs
The following mappings use the same resolver pattern:
| CSV File | Business Key | Required Reference Resolvers | Important Option Resolvers | Generated Fields | Notes |
|---|---|---|---|---|---|
customers.csv |
organization_code + customer_code |
organization, branch, owner user, created_by user | crm_customer_type, crm_customer_status, crm_customer_group, crm_customer_sub_group, crm_lead_channel |
id, timestamps, owner assignment timestamps |
Owner history should be generated by service behavior. |
contacts.csv |
organization_code + customer_code + email/contact_name |
organization, customer, created_by user | none | id, timestamps |
Contact must belong to resolved customer. |
contact-shares.csv |
organization + contact + shared_to_user |
organization, customer, contact, shared users | none | id, shared_at, timestamps |
Target user must have organization membership. |
leads.csv |
organization_code + lead_code |
organization, branch, customer, contact, creator, marketing owner, sales assignee | crm_lead_status, crm_lead_followup_status, crm_lead_lost_reason, crm_product_type, crm_priority, crm_lead_awareness, crm_lead_channel |
id, timestamps, assignment timestamps |
Lead outcome defaults to open. |
opportunities.csv |
organization_code + opportunity_code |
organization, lead, customer, contact, creator, updater, assignee | crm_product_type, crm_opportunity_status, crm_priority, crm_lead_channel, outcome/cancel/no-quotation reasons |
id, timestamps, assignment/lifecycle timestamps |
Validate contact/customer and optional lead lineage. |
opportunity-parties.csv |
opportunity + customer + role_code |
organization, opportunity, customer | crm_project_party_role |
id, timestamps |
Used by revenue attribution. |
quotations.csv |
organization_code + quotation_code |
organization, opportunity, customer, contact, branch, users, parent quotation | crm_quotation_type, crm_quotation_status, crm_currency, crm_discount_type, crm_sent_via |
id, timestamps |
Runtime approval/PDF fields must not be accepted from CSV. |
quotation-items.csv |
quotation + item_number |
organization, quotation | crm_product_type, crm_unit, crm_discount_type |
id, timestamps |
Validate numeric price fields. |
quotation-parties.csv |
quotation + customer + role_code |
organization, quotation, customer | crm_project_party_role |
id, timestamps |
Used by quotation reporting/PDF context. |
quotation-topics.csv |
quotation + topic_key |
organization, quotation | crm_quotation_topic_type |
id, timestamps |
topic_key is import-only alias. |
quotation-topic-items.csv |
quotation + topic_key + sort_order |
organization, quotation topic by import alias or existing lookup | none | id, timestamps |
Topic must be preview-resolved before commit. |
Business CSV field transforms:
- Dates: accept
YYYY-MM-DD; API responses remain ISO UTC. - Booleans: accept
true,false,1,0,yes,no; normalize to boolean. - Amounts: parse decimal with
.; reject thousands separators in strict mode. - Pipe lists: split on
|, trim, reject empty tokens in strict mode. - Empty string: normalize to
nullfor nullable DB fields.
Business CSV fallback rules:
created_by_emailmay fall back to setup actor only when the CSV file explicitly omits it and the import run is wizard-owned.updated_by_emailmay fall back tocreated_by_email.branch_codemay fall back to the wizard default branch.currencymay fall back to organization default currency once that is persisted in setup state or organization metadata.- Option fields should not silently create new options unless import mode is
allowOptionCreate.
Unsupported Mapping Decisions
| CSV | Mapping Decision |
|---|---|
departments.csv |
Block. No first-class schema. |
teams.csv |
Block. No first-class team graph; security docs note team-scope limitations. |
warehouses.csv |
Block. No first-class schema. |
sites.csv |
Block. Current project location is text on lead/opportunity/quotation. |
services.csv |
Block. No first-class service catalog. |
price-books.csv |
Block. No price book foundation. |
tax-rates.csv |
Block. No tax rate table; quotation/item rows carry tax numbers. |
attachments.csv |
Defer. Needs binary upload/storage import design, not pure CSV. |
email-settings.csv |
Block. No secure first-class email settings table. |