Trois systèmes, une date de réception: le lot de 00:30 et le jour de l'usine
Objectif Fusionner en une entité la date d'arrivée d'un lot telle que le LIMS, l'ERP et le transporteur la donnent, et ne garder en litige que les vrais écarts.
Une usine reçoit ses lots de matière première. Trois systèmes disent quand: le LIMS scanne l'échantillon (un instant), l'ERP saisit la réception (une date), le transporteur écrit « Livré le » dans un CSV (du texte).
lus tels quels, le texte du transporteur met la colonne en texte: douze lots en litige;
typée, une date rencontre une heure au jour UTC: le lot de l'équipe de nuit est en litige;
avec zone: Europe/Paris, il reste un litige, la vraie faute de saisie.
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]