Vlastni skripty firmy: prevod dat v JS, v logu vstup i vystup

Klikaci pravidla jsou u peti poli rychlejsi, ale u modelu objednavky je jich
dvacet a v tom se necte. Vedle nich proto skript firmy: prevod z A do B
napsany v JS, jeden na zakaznika.

- Skripty se ukladaji do uloziste, ne na disk. Disk je uvnitr kontejneru
  a redeploy ho vymaze.
- Krok Transformace dat - Vlastni skript. Vysledek jde dal jako krok.result.
- V logu ticketu je u kroku vstup i vystup. Prave to byl duvod, proc skript
  nad pravidly vyhral.
- Zkouska bez ulozeni: v portalu se vlepi skutecne telo a hned je videt, co
  z toho leze.
- Skripty jsou v zalozce Akce, vedle definic akci. Obojí je popis toho, co
  aplikace ve firme umi, a spravuje to tentyz clovek.

Skript je ciste prevod hodnot: dostane input, vrati objekt. Nema require,
import, process, fetch ani console, bezi nejvys 2 s a vysledek se vejde do
256 kB. node:vm neni bezpecnostni hranice proti nekomu, kdo se chce dostat
ven - je to izolace proti nehode a proti zacykleni.

Pri zkousce se ukazalo, ze casovy limit nepokryval samotny beh: runInContext
jen vyrobil funkci a zavolat ji zvenku znamenalo, ze while (true) uvnitr
zablokovalo proces navzdy. Kod se ted vola uvnitr runInContext.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
JiriUhlir
2026-08-20 08:08:09 +02:00
co-authored by Claude Opus 5
parent 99561c4682
commit e4779caf82
12 changed files with 1063 additions and 6 deletions
+1
View File
@@ -38,6 +38,7 @@ React aplikaci ze slozky `dist/public`.
| Konektory za firmu | hotovo | pristupove udaje v konektoru, overeni napojeni |
| Transformace dat | hotovo | pravidla i sablona JSON, kroky si predavaji struktury |
| Prace nad celym modelem | hotovo | ukazka tela, cesty v sablonach, smycka nad seznamem |
| Vlastni skripty firmy | hotovo | prevod dat v JS, v logu vstup i vystup |
| Sprava clenstvi z portalu | hotovo | firmy a role v Nastaveni, lide a pozvanky v Lidech |
| Role a prava jako data | hotovo | 26 prav v katalogu, vlastni role za firmu |
| Zalozky a limity za firmu | hotovo | navigace chodi ze serveru, ne z kodu klienta |
+29
View File
@@ -41,6 +41,35 @@ neprojde kontrolou. Radek s vystupem kroku je nejrychleji rostouci tabulka
v systemu (viz [10-runtime-a-kapacita.md](10-runtime-a-kapacita.md)), takze
hranice patri do kontroly parametru, ne az do uklidu databaze.
## Tri zpusoby, jak prevest data
| Zpusob | Kdy se hodi |
| --- | --- |
| **Pravidla** (`transform/map-fields`) | par poli, prevody hodnot, klikatelne |
| **Sablona JSON** (`transform/to-json`) | hlavni prace je ve **tvaru** vysledku |
| **Skript firmy** (`transform/custom`) | slozitejsi prevod, kde je kod citelnejsi nez dvacet pravidel |
Skript je JS: dostane `input`, vrati objekt. Nevola nic ven a v logu je u nej
**vstup i vystup**, takze kdyz vysledek nesedi, neni potreba hadat, co do
prevodu vlezlo. Podrobnosti v [99-zmeny.md](99-zmeny.md), zaznam z 2026-08-20.
```js
const order = input.data.order;
return {
documentSerialNumber: order.code,
dateOfIssue: util.day(order.creationTime),
items: order.items.map((p) => ({
name: p.name,
amount: util.num(p.amount),
unitPrice: util.num(p.unitPrice.withoutVat),
})),
};
```
Pravidla tim neztraceji smysl: u peti poli je vyber ze seznamu rychlejsi a
nemuze se v nem udelat preklep v zavorce.
## Dva rezimy
Obe moznosti stoji na tom samem enginu v `src/scripts/mapping.ts`.
+48
View File
@@ -2,6 +2,54 @@
Nejnovejsi nahore.
## 2026-08-20 - vlastni skripty firmy: prevod dat v JS
Klikaci pravidla jsou u peti poli rychlejsi, ale u modelu objednavky je jich
dvacet a v tom se necte. Proto vedle nich **skript firmy**: prevod z A do B
napsany v JavaScriptu, jeden na zakaznika.
### Pridano
- **Skripty firmy** (`src/data/tenantScripts.ts`). Uklada se do uloziste, ne na
disk - disk je uvnitr kontejneru a redeploy ho vymaze.
- **Krok Transformace dat - Vlastni skript.** Vybere se skript a zdrojova data,
vysledek jde dal jako `{{krok.result}}`.
- **V logu je vstup i vystup.** Prave to byl duvod, proc skript nad pravidly
vyhral: kdyz vysledek nesedi, neni potreba hadat, co do prevodu vlezlo.
- **Zkouska bez ulozeni.** V portalu se vlepi skutecne telo a hned je videt, co
z toho leze. Bez toho by se chyba poznala az z padleho behu.
- Skripty jsou v zalozce **Akce**, vedle definic akci. Obojí je popis toho, co
aplikace ve firme umi, a spravuje to tentyz clovek pod pravem `action.manage`.
### Co skript smi a co ne
Skript je **ciste prevod hodnot**: dostane `input`, vrati objekt. Nema `require`,
`import`, `process`, `fetch` ani `console`. Volani ven patri do kroku konektoru,
ktery ma pristupove udaje, opakovani i zapis do logu.
| Pojistka | Proc |
| --- | --- |
| limit 2 s | zacykleny skript by jinak zablokoval workera vsem firmam |
| vysledek do 256 kB | vetsi objekt uz stejne nikdo dal nezpracuje |
| kod do 20 000 znaku | delsi uz neni prevod, ale aplikace |
| zadny stav mezi behy | stav, ktery prezije beh, je zdroj nejhur hledanych chyb |
**Cim to neni.** `node:vm` neni bezpecnostni hranice proti nekomu, kdo se chce
dostat ven. Je to izolace proti nehode a proti zacykleni. Skript pise spravce
te same firmy, tedy nekdo, kdo jeji data stejne vidi. Kdyby mel skripty psat
nekdo zvenku, patri to do samostatneho procesu s vlastnimi pravy.
### Opraveno pri tom
- **Casovy limit nepokryval samotny beh.** Prvni verze pouzila `runInContext`
jen na vyrobu funkce a zavolala ji az potom zvenku - `while (true) {}` uvnitr
ni zablokovalo proces navzdy. Zjisteno pri zkousce, ktera se zasekla. Kod se
ted vola uvnitr `runInContext`, takze limit plati.
- Chyba z limitu nese prototyp z kontextu skriptu, takze `instanceof Error` na
ni neplati. Pozna se podle textu.
- `console` v novem kontextu existuje samo od sebe a psalo by do logu serveru.
Odebrano.
## 2026-08-20 - prace nad celym modelem, ne nad plochym seznamem poli
Odesilatel posle cely model - objednavka ze Shoptetu ma zanoreni, ceny