refactor: form-core wiring, JWT sessions, slowapi, packaging, frontend rewrite, test declutter

This commit is contained in:
Jonas Miederer 2026-09-28 18:03:07 +02:00
parent 06ab25fb47
commit 03af41e837
74 changed files with 6089 additions and 5183 deletions

View file

@ -44,10 +44,30 @@ derives a JSON Schema + uiSchema from the node's template
The API watcher syncs + deploys it automatically; the form schema is
regenerated per version.
## Branched questionnaires (`visible_if`)
## Structured `visible_if` (preferred) + markers (fallback)
A field can appear only when other fields have certain values — nested
to any depth. Declare it in the code editor with a marker in `info`:
to any depth. Preferred: structured `visible_if` key (no quoting
mini-language, rename-refactorable, validated at sync time with warnings
instead of silent fail-open):
```python
(
DropdownInput(
name="bestandteil",
display_name="Welcher Bestandteil der Kirche?",
options=["Glocke", "Orgel"],
value=[],
info="Mehrfachauswahl möglich",
visible_if=[{"field": "gebaeude", "value": "Kirche"}],
required=True,
),
)
```
Legacy `[visible_if ...]` markers in `info` still work as deprecated
fallback (same syntax, stripped from help text). The parser emits
`allOf`/`if`/`then` branches either way (see below).
```python
(
@ -149,20 +169,23 @@ envelope and merge normally), and unasked code defaults stay out of
the output. Without the list — raw dicts, Langflow playground — all
visible declared defaults apply as before.
## Variant flows (own component per flow)
## Variant flows (own component per flow, shared core)
A flow whose fields differ from `CustomInputForm` gets its own
standalone component (see `bauvorhaven_form.py` → "Bauvorhaben Form"
in the palette): same class pattern, own `inputs` list. Standalone
means it: no imports between form modules — the LFX runtime executes
the embedded module source without our `kirche` package, so every form
component must be self-contained (stdlib + `lfx` only). Copy the file
as the starting point for future forms.
A flow whose fields differ from `CustomInputForm` gets its own thin
component (see `bauvorhaben_form.py` → "Bauvorhaben Form" in the
palette): same class pattern, own `inputs` list, shared runtime from
`kirche._form_core` (`from kirche._form_core import ...` plus the
`# <-- _form_core inlined ... -->` marker). The LFX runtime executes
the embedded module source without our `kirche` package, so
`scripts/make_flow_fixtures.py:kirche_node()` inlines the core into the
exported `code` — one truth in the repo, self-contained JSON. Copy the
file as the starting point for future forms.
Rule: code-declared inputs must equal template fields
(`test_embedded_code_matches_template_fields` enforces it; required
Multiselect uses the `[" "]` sentinel). Generate node + flow with
`kirche_node(..., component_cls, code_override)` and
(`test_embedded_code_matches_template_fields` enforces it, plus
no-sibling-import + core-present asserts; required Multiselect uses
the `[" "]` sentinel). Generate node + flow with `kirche_node(...)`
(which composes thin source + `_inline_core()` automatically) and
`build_bauvorhaben()` in `backend/scripts/make_flow_fixtures.py`
rather than hand-editing JSON. Restart Langflow afterwards so the
palette picks up the new component, then build/upload the flow.