Skip to main content
Detection decides which spec applies to an incoming file. It’s a match_mode plus a list of rules.
"detection": {
  "match_mode": "composite",
  "rules": [
    { "type": "data_source", "codes": ["pos_polaris"] },
    { "type": "filename_matches", "pattern": "(?i)\\.sav$" }
  ]
}

Match modes

ModeLogic
anyAt least one rule matches (OR).
allEvery rule matches (AND).
compositeCustom combination (typically a data-source gate AND a filename/header test).

Rule types

TypeFieldMeaning
data_sourcecodes (string[])Restrict the spec to files coming from specific source systems.
filenamepattern (string)Exact filename match.
filename_matchespattern (regex)Filename matches a regular expression (e.g. "(?i)tickets"(?i) = case-insensitive).
columnscolumns (string[])The file’s columns must match this list exactly.
header_containscolumns (string[])The header row must contain all of these columns (subset, order-independent).
sheet_namepattern (string)An Excel sheet name matches exactly.

data_source codes

The codes array uses the canonical data-source identifiers, including:
pos_polaris, pos_ginkoia, pos_fastmag, pos_kezia, pos_lcv, pos_cegid,
pos_openbravo, pos_oracle, pos_sage, ecommerce_api, erp_sap, user_uploads
These are validated when specs are seeded — an unknown code fails fast.

A composite example

"detection": {
  "match_mode": "composite",
  "rules": [
    { "type": "data_source", "codes": ["pos_ginkoia", "user_uploads"] },
    { "type": "filename_matches", "pattern": "(?i)tickets" },
    { "type": "header_contains", "columns": ["Numéro", "Séquence", "Montant", "Mode paiement"] }
  ]
}
Reads as: the file comes from Ginkoia (or a manual upload) and its name contains “tickets” and its header has all four columns.
When several specs could match, the winner is chosen by priority then spec_version — see Anatomy → priority.