Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
81211d6
fix(flow-patterns): make the models pass the platform compiler
dialexpert Aug 31, 2026
d4a086a
docs(flow-patterns): English as the normative language
dialexpert Aug 31, 2026
673e06e
docs(flow-patterns): complete the companion Flow table
dialexpert Aug 31, 2026
da0278f
chore: take the running environment out of a public repository
dialexpert Sep 1, 2026
9cbd0e6
feat(flow-patterns): teaching examples written for this folder
dialexpert Sep 1, 2026
faf3b70
docs: rebuild the catalogue from the models
dialexpert Sep 1, 2026
b79ed38
fix(flow-patterns): lay the diagrams out, and say what actually runs
dialexpert Sep 2, 2026
05ade5c
fix(flow-patterns): a branch starts beside its source, not below the …
dialexpert Sep 2, 2026
3c4f5d0
fix(04-pagination): mark the collection, and correct what the mark does
dialexpert Sep 2, 2026
7c6df2e
docs: the boundary-event regression is fixed; say so, and say where
dialexpert Sep 2, 2026
fad4e4d
feat(flow-patterns): an example on every end event, and a link back t…
dialexpert Sep 2, 2026
75e647a
feat(flow-patterns): response headers, readable examples, one request…
dialexpert Sep 2, 2026
21b0123
docs(flow-patterns): fill in the example descriptions
dialexpert Sep 2, 2026
c16ed86
feat(tools): the rules these examples are held to, as code you can run
dialexpert Sep 2, 2026
7e73656
fix(tools): fit_notes formats the text a model already carries
dialexpert Sep 2, 2026
58073fc
feat(flow-patterns): every example is built from the specification be…
dialexpert Sep 2, 2026
78a7b54
feat(flow-patterns): every example runs, not just compiles
dialexpert Sep 2, 2026
1218245
feat(flow-patterns): files, folders and a link to the archive
dialexpert Sep 3, 2026
e51d30b
fix(parked): ai-completion лишає тільки ті помилки, що не в моделі
dialexpert Sep 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1233,7 +1233,7 @@
}
],
"cookie": [],
"body": "[\n{\n \"id\": \"204-52-24\",\n \"callback\": \"http://10.49.199.96:8080/api/kafka\",\n \"query\": \"esym_Method=ETG.Counter.Overlimit.Notification\"\n}\n]\n"
"body": "[\n{\n \"id\": \"204-52-24\",\n \"callback\": \"http://localhost:8080/api/kafka\",\n \"query\": \"esym_Method=ETG.Counter.Overlimit.Notification\"\n}\n]\n"
}
]
}
Expand Down
4,950 changes: 2,472 additions & 2,478 deletions 3gpp-apis/3GPP_Rf_Rating_Function/3GPP-Rf_Rating_postman_collection.json

Large diffs are not rendered by default.

228 changes: 113 additions & 115 deletions CATALOGUE.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Kafka_getConfig/Kafka.bpmn
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<gp:globalParameter name="UsedLibs">[{"name":"Create_Config_Yiz_Http","link":"activities://bpmn-mnemo/personal/MyDrafts/Create_Config_Yiz_Http/#latest","version":"","entities":[]},{"name":"bll","link":"libs://common/bll","version":"","entities":[]},{"name":"ai","link":"libs://common/ai","version":"","entities":[]},{"name":"Platform","link":"libs://common/platform","version":"","entities":[]}]</gp:globalParameter>
<gp:globalParameter name="Functions">[{"name":"RestApi","initCode":"functions://default/RestApi","initParameters":[{"name":"Uri","type":"Uri","required":true,"oldName":"Uri","defaultValue":"http://servername:port/resource"},{"name":"Method","type":"String","required":true,"oldName":"Method","defaultValue":"GET"},{"name":"Login","type":"String","required":false,"oldName":"Login","defaultValue":null},{"name":"Password","type":"String","required":false,"oldName":"Password","defaultValue":null},{"name":"Headers","type":"StringDictionary","required":false,"oldName":"Headers","defaultValue":"{\r\n \"Content-Type\":\"application/json;charset=utf-16\",\r\n \"system\":\"204\",\r\n \"global_unique_id\":\"6a297fcb-956e-4228-8c11-017e9bacd629\"\r\n }"},{"name":"Body","type":"String","required":false,"oldName":"Body","defaultValue":"{}"},{"name":"Encoding","type":"String","required":false,"oldName":"Encoding","defaultValue":"utf-8"},{"name":"Timeout","type":"int","required":false,"oldName":"Timeout","defaultValue":"0"},{"name":"Result","type":"HttpResponse","required":false,"oldName":"Result","defaultValue":null}],"oldName":"RestApi"},{"name":"RestApi/GET","initCode":"functions://default/RestApi/Get","initParameters":[{"name":"Uri","type":"Uri","required":true,"oldName":"Uri","defaultValue":"http://servername:port/resource"},{"name":"Login","type":"String","required":false,"oldName":"Login","defaultValue":null},{"name":"Password","type":"String","required":false,"oldName":"Password","defaultValue":null},{"name":"Headers","type":"StringDictionary","required":false,"oldName":"Headers","defaultValue":"{\r\n \"Content-Type\":\"application/json;charset=utf-16\",\r\n \"system\":\"204\",\r\n \"global_unique_id\":\"6a297fcb-956e-4228-8c11-017e9bacd629\"\r\n }"},{"name":"Encoding","type":"String","required":false,"oldName":"Encoding","defaultValue":"utf-8"},{"name":"Timeout","type":"int","required":false,"oldName":"Timeout","defaultValue":"0"},{"name":"Result","type":"HttpResponse","required":false,"oldName":"Result","defaultValue":null}],"oldName":"RestApi/GET"},{"name":"JsonPath","initCode":"functions://default//JsonPath","initParameters":[{"name":"Response","type":"HttpResponse","required":true,"oldName":"Response","defaultValue":null},{"name":"Path","type":"String","required":false,"oldName":"Path","defaultValue":"$"},{"name":"Result","type":"Json","required":false,"oldName":"Result","defaultValue":null}],"oldName":"JsonPath"},{"name":"SaveVariable","initCode":"functions://default//SaveVariable","initParameters":[{"name":"VariableName","type":"string","required":true,"oldName":"VariableName","defaultValue":"varName"},{"name":"Data","type":"object","required":true,"oldName":"Data","defaultValue":"#previous"}],"oldName":"SaveVariable"},{"name":"SQL/Oracle/Query","initCode":"functions://default//SQL/Oracle/Query","initParameters":[{"name":"userID","type":"String","required":true,"oldName":"userID","defaultValue":null},{"name":"password","type":"String","required":false,"oldName":"password","defaultValue":null},{"name":"dataSource","type":"String","required":false,"oldName":"dataSource","defaultValue":null},{"name":"query","type":"String","required":false,"oldName":"query","defaultValue":null},{"name":"Result","type":"Collection","required":false,"oldName":"Result","defaultValue":null}],"oldName":"SQL/Oracle/Query"},{"name":"SQL/Oracle/Command","initCode":"functions://default//SQL/Oracle/Command","initParameters":[{"name":"userID","type":"String","required":true,"oldName":"userID","defaultValue":null},{"name":"password","type":"String","required":false,"oldName":"password","defaultValue":null},{"name":"dataSource","type":"String","required":false,"oldName":"dataSource","defaultValue":null},{"name":"command","type":"String","required":false,"oldName":"command","defaultValue":null},{"name":"Result","type":"int","required":false,"oldName":"Result","defaultValue":null}],"oldName":"SQL/Oracle/Command"}]</gp:globalParameter>
<gp:globalParameter name="ExternalDefinitionLib">[]</gp:globalParameter>
<gp:globalParameter name="Parameters">[{"name":"sseMsg","type":"SseMessage","initialValue":""},{"name":"httpConfig","type":"HttpConfig","initialValue":"{\r\n \"host\":\"https://10.29.101.122\",\r\n \"port\":\"6992\",\r\n \"login\":\"login\",\r\n \"password\":\"password\",\r\n \"encoding\":\"utf-8\",\r\n \"headers\":{\r\n \"Content-Type\":\"application/vnd.api+json\",\r\n \"Accept\":\"application/vnd.api+json\"\r\n }\r\n}\r\n"},{"name":"oracleConfig","type":"OracleConfig","initialValue":"{\r\n \"userId\":\"login\",\r\n \"password\":\"password\",\r\n \"dataSource\":\"10.49.1.198:1521/bisdb_prm.kyivstar.ua\"\r\n}\r\n"}]</gp:globalParameter>
<gp:globalParameter name="Parameters">[{"name":"sseMsg","type":"SseMessage","initialValue":""},{"name":"httpConfig","type":"HttpConfig","initialValue":"{\r\n \"host\":\"https://localhost\",\r\n \"port\":\"6992\",\r\n \"login\":\"login\",\r\n \"password\":\"password\",\r\n \"encoding\":\"utf-8\",\r\n \"headers\":{\r\n \"Content-Type\":\"application/vnd.api+json\",\r\n \"Accept\":\"application/vnd.api+json\"\r\n }\r\n}\r\n"},{"name":"oracleConfig","type":"OracleConfig","initialValue":"{\r\n \"userId\":\"login\",\r\n \"password\":\"password\",\r\n \"dataSource\":\"localhost:1521/XEPDB1\"\r\n}\r\n"}]</gp:globalParameter>
<gp:globalParameter name="DebugParamas">{"brokers":"kafka1:9092,kafka2:9092","groupId":"gw-reader","topic":"payments.events","security":{"ssl":true,"mechanism":"PLAIN","username":"user","password":"secret"}}</gp:globalParameter>
</extensionElements>
<process id="Process_1llnnqn" name="Kafka">
Expand Down
2 changes: 1 addition & 1 deletion api-call/Source.cs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ private void _initNodes()
System.Uri Uri=default(System.Uri);
try
{
Uri=new Uri($"https://anyapi.io/api/v1/email?email={Input.address}&apiKey=eopl60isvuor0um4nppvgoqj1d1tcpdko7a89sr6uak80ap1jme083");
Uri=new Uri($"https://anyapi.io/api/v1/email?email={Input.address}&apiKey=YOUR_API_KEY");
}
catch(Exception e)
{
Expand Down
2 changes: 1 addition & 1 deletion api-call/api-call.bpmn
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
<task id="Activity_Get_msisdns" name="retrive the Data by http">
<documentation>the GET api call example to get data from https://anyapi.io/app/email-validation-api#docs</documentation>
<extensionElements>
<ep:elementParameter name="ElementImplementation">{"actionType":"Function","action":"RestApi/GET","actionParam":{"Uri":"https://anyapi.io/api/v1/email?email={Input.address}&amp;apiKey=eopl60isvuor0um4nppvgoqj1d1tcpdko7a89sr6uak80ap1jme083","Login":"","Password":"","Headers":{"Content-Type":"application/vnd.api+json","global_unique_id":"6a297fcb-956e-4228-8c11-017e9bacd629"},"Encoding":"utf-8","Timeout":"0"},"libName":"","libEntity":"","libMethod":""}</ep:elementParameter>
<ep:elementParameter name="ElementImplementation">{"actionType":"Function","action":"RestApi/GET","actionParam":{"Uri":"https://anyapi.io/api/v1/email?email={Input.address}&amp;apiKey=YOUR_API_KEY","Login":"","Password":"","Headers":{"Content-Type":"application/vnd.api+json","global_unique_id":"6a297fcb-956e-4228-8c11-017e9bacd629"},"Encoding":"utf-8","Timeout":"0"},"libName":"","libEntity":"","libMethod":""}</ep:elementParameter>
</extensionElements>
<incoming>Flow_1lcy9oj</incoming>
<incoming>Flow_0onq684</incoming>
Expand Down
Binary file removed api-call/api-call.dll
Binary file not shown.
Binary file removed api-gateway/api-gateway.dll
Binary file not shown.
98 changes: 77 additions & 21 deletions flow-patterns/01-basics/README.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,90 @@
# 01 · Основи: конвеєр даних
# 01 · Basics: how data moves through a Flow

Найменші робочі Flow. Тут видно, як дані входять у процес, проходять елементами й виходять — без черг, файлів і паралельності.
The smallest Flow that still does something real: it takes typed input, passes it
through one step, and returns typed output.

## Коли застосовувати
## What this example demonstrates

Перший Flow. Або коли треба згадати, звідки береться `#Previous` і чим `Global` відрізняється від `Parameters`.
| Capability | Where to look |
|---|---|
| A typed process boundary | the start and end events, each tied to a data element |
| `Input` — what the caller sent | `T_Compose`, first line |
| `#Previous` — the previous node's result | `T_ParseConfig`, which casts it |
| Settings taken from a separate Flow | the `Get Config` Call Activity |
| An error path drawn on the diagram | the boundary event on `T_ParseConfig` |
| Writing to the run log | `Logger.LogInformation` |

## Файли
## The model

| Файл | Що показує |
|---|---|
| `echo-agent.bpmn` | мінімальний конвеєр: старт → задача → кінець; типізація входу й виходу одним типом |
| `global-and-jsonpath.bpmn` | `JsonPath` витягає значення з відповіді, `SaveVariable` кладе його в `Global`, наступні кроки читають |
```
start → Get Config → Parse Config → compose the greeting → end
↓ (on error)
handle Exception → end
```

Five nodes, and three of them are there before your own work begins. That is the
point of reading this one first.

## Types it declares

| Type | Kind | How it is used |
|---|---|---|
| `GreetingRequest` | inner, JSON Schema | the process boundary: the start event accepts it, the end event returns it. `Input.name` and `Input.language` are its fields |
| `ErrorResponse` | inner, JSON Schema | what `HandleException` returns, so a failure has a shape too |
| `ExternalConfig` | external → `types://external/ConfigActivity/Config` | the configuration type, declared **once** in `service-config` and only referenced here |

`ExternalConfig` is the one worth pausing on. This file never repeats the fields
of the configuration; it points at the Flow that owns them. Change the shape
there and every consumer sees the change, instead of each keeping a stale copy.

## What you should get back

```
POST .../flowdefinitions/personal/<library>/first-flow/Start.json?run=auto
{ "name": "Ada", "language": "en" }
```

```
HTTP 200
{"name":"Ada","language":"en"}
```

With an empty `name` the reply is `{"name":"world","language":null}` — the step
substitutes the default. The run log shows one line: `greeting Ada`.

## Why it is built this way

**The settings come from another Flow, not from this file.** The first two nodes
call `service-config` and cast its answer into `Parameters.config`. It looks like
ceremony in an example this small, and it is the single most important habit in
the group — see [03 · Configuration](../03-config-as-flow/) for what it buys you.

## Задіяні функції платформи
**The input is a declared type, not a loose bag.** The compiler can then tell you
that `Input.nmae` does not exist, instead of the process returning null at run
time and leaving you to guess.

`JsonPath` · `SaveVariable` · `RestApi`
**The error path exists even though nothing here can fail.** A boundary error
event sits on the parsing step, leading to a handler and its own end event.
Without it a failure ends the process silently.

## Зарезервовані слова
## Where newcomers stumble

`Input` · `#Previous` · `Parameters` · `Global` · `Logger`
- **`#Previous` is the previous node's result, not the process input.** After the
configuration steps, `#Previous` holds the configuration — not what the caller
sent. Reach for `Input` when you mean the caller's payload.
- **A step must return something.** The body of a task is compiled into a method
with a return type. A branch that falls off the end without `return` fails the
whole model with `CS0161`, and the message points at generated code you cannot
open.
- **Input and output share a type here.** That is fine for an echo. In a real
process each step usually deserves its own type; a shared one hides the moment
the shape actually changes.

## На що звернути увагу
## Run it

- `SaveVariable` пише **у `Global`**, а не в `Parameters`. Читати потім —
`Global.<ім'я>`, і воно доступне до кінця виконання процесу.
- `Global` — динамічний: помилку в імені компілятор не побачить, вона вилізе на
виконанні. Іменуйте змінні один раз і однаково.
- У `echo-agent` вхід і вихід — той самий тип. Це нормально для ехо, але в
реальному процесі кожен крок зазвичай має свій (див. TYPE-DESIGN §3.1).
Import `service-config.bpmn` from [03 · Configuration](../03-config-as-flow/)
into a **tenant** library first, under the name `flow-patterns-config`. Then
import this file and compile it.

---
Про типи даних у цих прикладах — [TYPE-DESIGN.md](../TYPE-DESIGN.md).
For how the types in this example are designed, see [TYPE-DESIGN.md](../TYPE-DESIGN.md).
Loading