9 KiB
9 KiB
Changelog
All notable changes to this project will be documented in this file. The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased]
Changed
- Declutter: shared
BaseApiClient(LFX/Langflow) with tenacity transport retry, singleget_db,model_validatemappers, unified LFX/Langflow error mapping, stream logic moved torunner.py,sync_full_passsingle orchestration (API+CLI), shared model base (utcnow/ts_column), unified auth counters,httpxindeploy_flow.py, atomicwrites file writes,secure-package headers. - Auth: stateless JWT sessions (HS256, 30d, HttpOnly cookie unchanged) replace the
user_sessionstable (Alembic revision drops it; all sessions invalidated at deploy); slowapi run throttle replaces the hand-rolled sliding window; mail via jinja template + fastapi-mail (same copy/fallback contract); CLIs on typer;JWT_SECRETenforced bycheck_prod.py. - Forms: thin variant components over shared
components/kirche/_form_core.py(codegen-inlined bykirche_node()for LFX; all 5 flows regenerated + level-4 validated), structuredvisible_ifkey alongside legacy markers,LangflowClient.upsert_flow+scripts/push_flows_to_langflow.py(6 canonical flows pushed to Langflow UI). - Store/sync: single
next_version_noquery per version, validation only at thecreate_versionchoke point, mtime-cached.flowsignore. - Tests (full real LFX kept): shared
conftesthelpers +tests/_harness.pyadopted by fixtures and smoke script, parametrized matrices (export stems, check_prod env, deploy failures, sync listing failures, API auth probes, input_schema types), relaxed brittle asserts (ui:order sets, per-flag cookie asserts, SSE any-match). - Frontend: react-query reads + notifications,
useForm+zod static forms, sharedDecisionButtons/ErrorAlert/JsonView/FormattedDate/RunsTable/Landingblocks, new aggregateGET /api/runskills the Tasks N+1,Promise.allversion fetches,sharpicons, selector-based screenshots, dead photo removed.
Added
- Aggregate
GET /api/runs(tenant-scoped runs with flow names, single query). - Branched questionnaires:
[visible_if feld=Wert]markers in aCustomInputFormfield'sinfo(code editor) show the field only when the condition holds — nested to any depth, with&for AND conditions and quotes for values with spaces. The parser emitsallOf/if/thenbranches (branch-scopedrequired, template-order placement); unknown triggers, cycles, and unsupported trigger types fail open (always visible). New demo flowbauvorhaben.json(4 levels + sibling branch + bool trigger). Values of hidden fields are kept and submitted. - Run envelope carries the asked field names (
fields, from the version's form schema):collect()emits defaults only for asked AND currently visible fields (hidden branch fields stay out, like the frontend never submits them), so templates may declare fields unknown to the component code and unasked code defaults stay out of the run output. Without the list (raw dicts, Langflow playground) all visible declared defaults apply. - Standalone
CustomInputBauvorhabencomponent ("Bauvorhaben Form" in the kirche palette, zero shared code withCustomInputForm— the LFX runtime executes embedded module source without our package); the bauvorhaben flow uses it, and Langflow no longer normalizes the node back to the default form on import. - Form parser also recognizes user-built
CustomComponentnodes whose display name ends with"Form"(e.g. Mitarbeiter Einstellen Form) — same template contract, no kirche base needed. - Standalone
CustomInputMitarbeitercomponent ("Mitarbeiter Einstellen Form") with hiring flow incl. Gehaltsrechner, rebuilt generator-owned. - Admin flow table shows one row per flow (latest version, with live version note when an older version is deployed) instead of one row per version.
- Step-by-step guide for new workflow modules:
docs/new_workflow_module.md(linked from README).
Changed
CustomInputForm.collect()is now dynamic and returnsData(JSON) instead ofMessage: fields can be renamed, added, or removed in the Langflow code editor with nocollect()change, and values travel as a real JSON object. The form parser keepsnamekeys verbatim (empty names skipped, collisions suffixed) and the run envelope merges unknown keys. Note: a terminalChatOutputrendersDataas a fenced ```json block, and downstream components should read.data, not.text.
Added
- Flow-Sync ist jetzt ein manueller Full-Pass:
POST /api/flows/sync(Button "Aus Langflow synchronisieren" in der Verwaltung) holt erst alle Flows aus Langflow nachbackend/flows/*.jsonund deployed sie danach automatisch (Report mitpulled-Liste). Der Hintergrund-Beobachter und der Startup-Sync bleiben dateibasiert. Die Verwaltung zeigt eine deutsche Schritt-Anleitung direkt beim Sync-Button. - LLM-Provider-Umgebung für Langflow:
OPENAI_API_KEY+OPENAI_BASE_URLin.env(OpenAI-kompatible Endpoints) erzeugen automatisch restart-feste Global Variables in Langflow; LFX liest dieselben Werte. - Langflow-Sitzungen halten länger:
LANGFLOW_REFRESH_TOKEN_EXPIRE_SECONDS(Default weiter 7 Tage, Dev-Beispiel 90) + stabile JWT-Signatur viaLANGFLOW_SECRET_KEY— kein Re-Login nach Container-Restarts.
Fixed
- Flow-Sync aus Langflow: neue Flows blieben unsichtbar, weil LFX-Uploads
mit
Permission deniedscheiterten (named Volume root-owned, LFX läuft rootless).lfx-entrypoint.shchownt/flowsper gosu vor dem Start; zusätzlich Pull-Dedup (wiederverwendet gleichnamige/identische Dateien statt Bindestrich-Duplikate wiesimple-rule.json, die jede Sync-Meldung mit Namenskonflikten füllten). - Sync-Dateinamen behalten die Langflow-Namen (
test_flow.jsonstatttest-flow.json; nur dateisystem-reservierte Zeichen werden ersetzt). - Gezogene Flow-Dateien sind world-readable (0o644):
mkstemperzeugte 0o600-Dateien, die Langflow beim Start abstürzen ließen (Permission deniedin/app/flows, Crash-Loop) und der API Fehler (unreadable) verursachten. LANGFLOW_SECRET_KEYmuss ein gültiger Fernet-Key sein (44 Zeichen, urlsafe-base64): ein Hex-String brach die Variablen-Verschlüsselung mitFernet key must be 32 url-safe base64-encoded bytes(500 beim Anlegen von Global Variables — Provider-Keys ließen sich nicht speichern)..env.exampledokumentiert die Erzeugung.- LFX runtime user gets a home directory (
useradd -m,HOMEset): without one every flow run failed with "Settings service not found".
Security
- Production ops:
scripts/check_prod.pyvalidates.envsecrets and modes before deploy (with tests); README production checklist (proxy gates for Langflow, secret rotation, upgrade runbook).
Security
- API authorization: flow management is admin-only, runs and run/approval
reads require login with strict session-tenant scoping, approval
decisions record the session user, and flow callbacks authenticate with
a shared
X-Callback-Token(CALLBACK_TOKEN). Request-controlledtenant_id,callback_base_urlandcontinuation_flow_idwere removed (SSRF / cross-tenant / flow-chaining hardening); continuations now resolve from the admin-authored definition. - Frontend:
/app/*routes require login; approver is the session user. - Edge hardening: interactive API docs only with debug, security headers (nosniff/frame/Referrer-Policy), 2 MiB body cap, per-IP run throttle, generic upstream-error responses, magic links never logged.
- Containers run rootless (api/vite as uid 1000, lfx as
lfxuser); frontend fails closed to preview mode unlessFRONTEND_MODE=dev.
Added
- Landing page: status-quo problem block, 5-step process with quote, portal overview with admin areas, AI platform parts, exception tiers, quantified benefits, integrations, use-case examples, pilot-program section, expanded FAQ (8 items incl. KI data usage, price model, responsibility).
Changed
- Landing page copy overhauled after 3 reviewer rounds (church-admin compliance wording: "entwickelt nach DSG-EKD/DSGVO" + AVV/TOMs, human release responsibility, honest pilot framing instead of invented testimonials; CTA now "Pilotgespräch vereinbaren").
- New photo
pilot-meeting.webp(consultation scene, self-hosted). - Backend lint + format standards via ruff (pinned dev dependency,
enforced in CI):
uv run ruff check .,uv run ruff format.
[0.1.0] - 2026-09-13
Added
- Repo scaffold: docker-compose dev/prod, version-pinned images, devcontainer.
- Magic-link auth, access requests, RBAC, frontend access-management UI.
- File-based flow source of truth + sync engine + LFX runtime.
- RJSF dynamic forms, router, Mantine dark-mode design system.
- Conversion landing page, automated screenshots, bell-tower favicon.
- Email-first login, branded multipart HTML magic-link mails.
- lfx level-4 validation on all canonical flows + regression test.