lumnik. / scenarios All scenarios · Français

A technician sees only the maintenance app

Goal Give each business line its app on the same hub, without a technician being able to read purchasing's data.

Maintenance and purchasing share an ERP where everyone sees everything. On the same hub, lumnik composes one app per business line.

workorders-1-day.csv
wo_id;asset;priority;status
WO-101;Convoyeur ligne 2;URGENT;OPEN
WO-102;Compresseur atelier B;NORMAL;OPEN
WO-103;Four de cuisson;LOW;CLOSED
invoices-1-day.csv
invoice_id;supplier;amount;status
INV-501;Fournisseur Alpha;18500;OPEN
INV-502;Fournisseur Beta;2300;OPEN
INV-503;Fournisseur Gamma;12750;OPEN
$ lm --context maintenance app list
NAME                    TITLE        SCOPE        ICON     ACCENT   BACKGROUND  DEFAULT  TABS
scenario-maintenance-b  Maintenance  maintenance  generic  #8b7ff0  #14121f              (all)
$ lm --context maintenance view list
NAME                          SCOPE        TITLE
scenario-metier-workorders-b  maintenance  Ordres de travail

$ lm --context maintenance view scenario-metier-workorders-b
Ordres de travail

Ordre   Équipement             Priorité  Statut
WO-000  calibration            LOW       CLOSED
WO-101  Convoyeur ligne 2      URGENT    OPEN
WO-102  Compresseur atelier B  NORMAL    OPEN
WO-103  Four de cuisson        LOW       CLOSED

$ lm --context maintenance view scenario-metier-invoices-b
Error: access refused (403): scope not granted
$ lm --context maintenance entity get ScenarioWorkOrderB -o json
[
  {
    "wo_id": "WO-000",
    "asset": "calibration",
    "priority": "LOW",
    "status": "CLOSED",
    "_conflicts": "{}"
  },
  {
    "wo_id": "WO-101",
    "asset": "Convoyeur ligne 2",
    "priority": "URGENT",
    "status": "OPEN",
    "_conflicts": "{}"
  },
  {
    "wo_id": "WO-102",
    "asset": "Compresseur atelier B",
    "priority": "NORMAL",
    "status": "OPEN",
    "_conflicts": "{}"
  },
  {
    "wo_id": "WO-103",
    "asset": "Four de cuisson",
    "priority": "LOW",
    "status": "CLOSED",
    "_conflicts": "{}"
  }
]

$ lm --context maintenance entity get ScenarioSupplierInvoiceB
Error: access refused (403): scope not granted
$ lm --context maintenance inbox --process scenario-metier-urgent-wo-b
ID   WHEN      PROCESS                      MESSAGE                                        ENTITY_KEY
248  just now  scenario-metier-urgent-wo-b  Urgent work order WO-101 on Convoyeur ligne 2  a61f7e7532807c18c48f0cc3126fe9e6ccdc6def4aa35b3723ec3b1dc2f953b6
$ lm --context maintenance inbox ack 255
Error: API error 404: no decision 255 in your inbox

Limits

  • The métier is a Keycloak role scope:<tag>; a user with no scope: role at all sees the whole tenant.
  • An unknown entity answers 404, another métier's 403: names can be told apart, never rows.
  • The scenario goes through lm; the PWA reads the same doors.
  • Synthetic data.

Maintenance · purchasing

In the ERP, everyone sees everything.

The technician sees supplier invoices.

Maintenance and purchasing share the same database.

Fictional company · synthetic data

The problem

Opening the data opens it to all.

  • One screen per business line is not enough.
  • A direct query bypasses the screen.
  • A known id opens someone else's decision.

Nothing is changed

The ERP and Keycloak stay in place.

  • The business line is a Keycloak role.
  • lumnik reads it, it does not manage it.
  • No application to build.

What had to be written

spec:
  title: Maintenance
  scope: maintenance

Every manifest carries its scope.

A 126-line scenario, ten declaration files.

What the technician sees

One app, one view, four orders.

  • The Maintenance app alone.
  • The four work orders.
  • The urgent order's decision.

What they do not see

Every purchasing door refuses.

lm --context maintenance
access refused (403): scope not granted

Real answer, replay of 3 November 2026, Keycloak OIDC.

The limit

With no scope role, a user sees the whole tenant.

  • The business line is set in Keycloak.
  • An unknown entity answers 404, another line's 403.
  • Names can be told apart, never rows.

Try it

The scenario replays end to end.

Two business lines, one hub, a real Keycloak: every step is published with its output.

This scenario runs on lumnik Open, free and open source.

Try lumnik Open →