Three systems, one receipt date: the 00:30 batch and the plant's day
Goal Fuse into one entity a batch's arrival date as the LIMS, the ERP and the carrier give it, and keep in dispute only the real disagreements.
A plant receives its batches of raw material. Three systems say when: the LIMS scans the sample (an instant), the ERP books the receipt (a date), the carrier writes "Livré le" in a CSV (text).
read as they are, the carrier's text makes the column text: twelve batches in dispute;
typed, a date meets a time at the UTC day: the night shift's batch is in dispute;
with zone: Europe/Paris, one dispute is left, the real typing mistake.
kind: Entityname: ScenarioReceivedBatchAdescription: "One batch of raw material as three systems saw it arrive: the lab's scan, the ERP's goods receipt, the carrier."scopes: [receiving-a]sources:-table: t_scenario_dates_lims_amap: { batch_no: batch_no, received_at: received }-table: t_scenario_dates_erp_amap: { batch_no: batch_no, receipt_date: received, supplier: supplier }-table: t_scenario_dates_carrier_amap: { batch_no: batch_no, delivered_on: received, dock: dock }match: [batch_no]
apiVersion: connectors.lumnik.io/v1kind: Connectormetadata:name: scenario-dates-carrier-aconnector_type: csv-filescopes: [receiving-a]spec:transport:kind: localpath: /tmp/lumnik-scenario/dates-across-sources/a/livraisons.csv # the carrier's delivery reportparser:delimiter: ";"encoding: ISO-8859-1has_header: falsecolumns: [batch_no, supplier, delivered_on, dock]after_process: nonemapping:dataset: - filter-where: { column: batch_no, regex: "L-[0-9]+" } # the header linecell: - parse-date: { column: delivered_on, formats: ["dd/MM/yyyy"] } # a day, no time: a date
$ lm apply -f manifests/21-carrier-typed.yamlApplied connector "scenario-dates-carrier-a" — 1 endpoint! 21-carrier-typed.yaml — 0 error(s), 1 warning(s) WARN spec.mapping.cell column "delivered_on" is text in connector.t_scenario_dates_carrier_a, and `parse-date` types it: a table keeps the types it was created with, so the next run writes the values into a text column → to retype it, delete the entities over this table, then `lm connector delete <connector> --force` (drops the table and its rows), apply the connector again and run it$ lm connector run scenario-dates-carrier-arun scheduled: befc3999-ff93-4fef-872a-943ae484878b$ lm run get befc3999-ff93-4fef-872a-943ae484878bID CONNECTOR ENDPOINT STATUS IN OUT SKIPPED DEAD-LETTERS STARTED ENDED EVALUATED
befc3999 scenario-dates-carrier-a default Completed 13 12 1 0 2026-11-07 21:49 2026-11-07 21:49 yes$ lm entity delete ScenarioReceivedBatchA --forcedeleted: ScenarioReceivedBatchA$ lm connector delete scenario-dates-carrier-a --forcedeleted: scenario-dates-carrier-a$ lm apply -f manifests/21-carrier-typed.yamlApplied connector "scenario-dates-carrier-a" — 1 endpoint$ lm connector run scenario-dates-carrier-arun scheduled: 0b95d4ce-9438-46bb-9085-d13f14d2d199$ lm run get 0b95d4ce-9438-46bb-9085-d13f14d2d199ID CONNECTOR ENDPOINT STATUS IN OUT SKIPPED DEAD-LETTERS STARTED ENDED EVALUATED
0b95d4ce scenario-dates-carrier-a default Completed 13 12 1 0 2026-11-07 21:49 2026-11-07 21:49 yes$ lm entity apply -f manifests/30-batch.yamlApplied entity "ScenarioReceivedBatchA" → connector."v_scenarioreceivedbatcha"$ lm entity get ScenarioReceivedBatchABATCH_NO RECEIVED SUPPLIER DOCK _CONFLICTS
L-0101 2026-11-05T07:12:00Z Chimie du Rhône Q1 {}
L-0102 2026-11-05T09:47:00Z Solvants de l'Est Q2 {}
L-0103 2026-11-05T13:20:00Z Arômes Provence Q3 {}
L-0104 2026-11-05T23:30:00Z Polymères Atlantique Q1 {"received": [{"src": "t_scenario_dates_lims_a", "value": "2026-11-05 23:30:00+00"}, {"src": "t_scenario_dates_erp_a", "value": "2026-11-06 00:00:00+00"}, {"src": "t_scenario_dates_carrier_a", "value": "2026-11-06 00:00:00+00"}]}
L-0105 2026-11-05T15:05:00Z Chimie du Rhône Q2 {}
L-0106 2026-11-05T22:40:00Z Solvants de l'Est Q3 {}
L-0107 2026-11-06T06:55:00Z Arômes Provence Q1 {}
L-0108 2026-11-06T08:31:00Z Polymères Atlantique Q2 {}
L-0109 2026-11-06T10:02:00Z Chimie du Rhône Q3 {"received": [{"src": "t_scenario_dates_lims_a", "value": "2026-11-06 10:02:00+00"}, {"src": "t_scenario_dates_erp_a", "value": "2026-11-04 00:00:00+00"}, {"src": "t_scenario_dates_carrier_a", "value": "2026-11-06 00:00:00+00"}]}
L-0110 2026-11-06T12:48:00Z Solvants de l'Est Q1 {}
L-0111 2026-11-06T14:26:00Z Arômes Provence Q2 {}
L-0112 2026-11-06T16:10:00Z Polymères Atlantique Q3 {}$ lm conflicts listENTITY KEY COLUMNS SOURCES
AcmeCustomer P-1000 name t_acme_desk_erp,t_acme_desk_crm
AcmeCustomer P-1002 city t_acme_desk_erp,t_acme_desk_crm
AcmeCustomer P-1008 city t_acme_desk_erp,t_acme_desk_crm
Customer C-004 city t_customers,t_crm_contacts
CustomerOfRecord 2c3830ad-a769-4a17-96fc-cc7948093f8b name t_scenario_resolution_erp,t_scenario_resolution_crm
CustomerOfRecord f6811b2c-307d-4810-8c53-c02b81fbfdb2 name,email t_scenario_resolution_erp,t_scenario_resolution_crm
member_a M-1001 full_name t_scenario_member_gestion_a,t_scenario_member_portail_a
member_a M-1003 plan t_scenario_member_gestion_a,t_scenario_member_portail_a
PiscineCustomer C-001 city,name t_piscine_ent_erp,t_piscine_ent_crm
PiscineCustomer3 C-001 city,name t_piscine_ent_erp,t_piscine_ent_crm,t_piscine_ent_legacy
PiscineCustomerCrmFirst C-001 city,name t_piscine_ent_crm,t_piscine_ent_erp
PiscineDup C-020 city t_piscine_ent_dup
PiscineGrounded C-001 city,name t_piscine_ent_erp,t_piscine_ent_crm
PiscineOrderLine CMD-1/1 qty t_piscine_ent_ord_a,t_piscine_ent_ord_b
ScenarioReceivedBatchA L-0104 received t_scenario_dates_lims_a,t_scenario_dates_erp_a,t_scenario_dates_carrier_a
ScenarioReceivedBatchA L-0109 received t_scenario_dates_lims_a,t_scenario_dates_erp_a,t_scenario_dates_carrier_a
ScenarioResolutionDriftA 12a10f8c-9583-4b3f-ab05-707a27418933 email t_scenario_resolution_drift_erp_a,t_scenario_resolution_drift_crm_a
ScenarioResolutionDriftB ee105795-90ef-4634-8eba-0cae7b839b4e email t_scenario_resolution_drift_erp_b,t_scenario_resolution_drift_crm_b
ScenarioResolutionDriftC ab091eb3-0425-477f-b98c-1f46d237dc5b email t_scenario_resolution_drift_erp_c,t_scenario_resolution_drift_crm_c
ScenarioResolutionDriftD 25e2850f-95c1-483d-bd08-9bef07408c27 email t_scenario_resolution_drift_erp_d,t_scenario_resolution_drift_crm_d
lm apply
WARN spec.mapping.cell
lm apply
column "delivered_on" is text in connector.t_scenario_dates_carrier_a, and `parse-date` types it: a table keeps the types it was created with, so the next run writes the values into a text column
lm apply
→ to retype it, delete the entities over this table, then `lm connector delete <connector> --force` (drops the table and its rows), apply the connector again and run it
kind: Entityname: ScenarioReceivedBatchAdescription: "One batch of raw material as three systems saw it arrive: the lab's scan, the ERP's goods receipt, the carrier."scopes: [receiving-a]zone: Europe/Paris # the plant's day: a date meets a time on the day it has in Parissources:-table: t_scenario_dates_lims_amap: { batch_no: batch_no, received_at: received }-table: t_scenario_dates_erp_amap: { batch_no: batch_no, receipt_date: received, supplier: supplier }-table: t_scenario_dates_carrier_amap: { batch_no: batch_no, delivered_on: received, dock: dock }match: [batch_no]