No description
Find a file
2026-09-13 21:14:43 +02:00
.devcontainer chore: add GCM with libicu76 dependency to devcontainer setup 2026-09-13 21:09:23 +02:00
.forgejo/workflows feat: unify on single repo-root compose file for dev and prod 2026-09-07 19:46:17 +00:00
backend feat: bell-tower favicon, lfx-clean flows, branded HTML mail 2026-09-13 17:57:42 +02:00
frontend feat: bell-tower favicon, lfx-clean flows, branded HTML mail 2026-09-13 17:57:42 +02:00
.env.example chore: phase 0 reproducible docker/dev setup with version pinning 2026-09-09 09:44:59 +00:00
.gitignore chore: phase 0 reproducible docker/dev setup with version pinning 2026-09-09 09:44:59 +00:00
AGENTS.md chore: document GCM credential setup in AGENTS.md 2026-09-13 21:14:43 +02:00
CHANGELOG.md chore: version 0.1 — changelog, VERSION file, agent workflow rules 2026-09-13 19:32:41 +02:00
docker-compose.yml fix: lfx boot, deploy key, and entrypoint perms for compose/devcontainer 2026-09-11 17:44:23 +02:00
Dockerfile.lfx fix: lfx boot, deploy key, and entrypoint perms for compose/devcontainer 2026-09-11 17:44:23 +02:00
opencode.json feat: initial project setup 2026-09-04 10:17:22 +00:00
PLAN_NEXT.md feat: bell-tower favicon, lfx-clean flows, branded HTML mail 2026-09-13 17:57:42 +02:00
README.md feat: bell-tower favicon, lfx-clean flows, branded HTML mail 2026-09-13 17:57:42 +02:00
transkript_ideen.md feat: initial project setup 2026-09-04 10:17:22 +00:00
VERSION chore: version 0.1 — changelog, VERSION file, agent workflow rules 2026-09-13 19:32:41 +02:00

Kirche Einfach

AI-assisted administration platform for church organizations.

Staff describe a request in plain words. The platform guides them through the process, checks the rules automatically, and asks a human only when something needs judgment. Every step is documented and traceable.

Features

  • Visual flow authoring — design decision flows in Langflow, then bring them into the platform.
  • Flows as files — each flow lives as one JSON file under backend/flows/. The directory is the source of truth: committed to git, reviewable, diffable.
  • Automatic sync — the API watches backend/flows/ and reconciles every change into the database and the runtime: new files become flows, edits become new versions, deleted files remove the flow (including its runs). Same on every startup; also triggerable via POST /api/flows/sync or uv run python scripts/sync_flows.py --sync.
  • Versioned runtime — every change creates an immutable version; versions deploy to the lightweight LFX runtime and can run synchronously or streamed.
  • Approvals — a flow can pause and ask a human for a decision. Approving can automatically start a follow-up ("continuation") flow.
  • Access management — public landing page (German) with an access-request form (request + approval). Approved users get a passwordless magic-link invite by email (SMTP via .env); sessions are HttpOnly cookies, tenants come from the session. First admin via POST /api/auth/admin-bootstrap (only on an empty user table, email must be in ADMIN_EMAILS).
  • Dynamic forms — flows declare form fields as typed inputs on a CustomInput* custom component (reusable library in backend/components/, mounted into Langflow via LANGFLOW_COMPONENTS_PATH). GET /api/flows/{id}/input-schema derives a JSON Schema + RJSF uiSchema from the deployed version; the webapp renders the matching form automatically. Flows without such a node fall back to a single textarea. See backend/components/kirche/README.md for authoring new form fields.
  • Web UI — landing page (Start), access request (Zugang), and the logged-in webapp: Workflows (choose + run with dynamic form), Aufgaben (approvals), Verwaltung (admin: access requests, import, sync, deploy).

Infrastructure

One docker-compose.yml at the repo root runs the whole stack — identical services in dev and prod. Dev-only needs (editor, SSH keys, autoreload, docker CLI) come from .devcontainer/devcontainer.json.

flowchart LR
    subgraph Repo["Git repo — source of truth"]
        FLOWS["backend/flows/*.json<br/>one Langflow export per flow"]
    end
    subgraph Stack["Compose stack (dev + prod)"]
        UI["frontend — React UI (3000)"]
        API["api — FastAPI (8000)<br/>+ embedded flow-watcher"]
        DB[("app.db — SQLite file")]
        LF["langflow — authoring UI (7860)<br/>langflow.db — SQLite file"]
        LFX["lfx — flow runtime (6004)"]
        WT["watchtower — nightly image updates (prod)"]
    end
    UI --> API
    FLOWS -->|watch + sync| API
    API -->|definitions · versions · runs · approvals| DB
    API -->|pull / export| LF
    API -->|upload · run · unregister| LFX
    LFX -->|approval callbacks| API
    WT -.->|updates :latest images| LF
Service Purpose URL
React frontend Web UI (Vite, HMR in dev) http://localhost:3000
FastAPI backend API + flow orchestration (reload in dev) http://localhost:8000
API docs Swagger UI http://localhost:8000/api/docs
Langflow Visual flow authoring http://localhost:7860
LFX Flow runtime (internal, no direct UI) localhost:6004
SQLite files backend/data/kirche.db (app), Langflow keeps its own file —

Why SQLite: a flow run needs only a handful of single-row statements, and Langflow itself runs on SQLite by default — so the whole stack works without a database server. Postgres can return later by changing DATABASE_URL (migrations stay portable).

.env holds only ubiquitous variables (identical value in dev and prod: secrets, service URLs). Dev-only variables travel via devcontainer.json (APP_ENV=dev); paths resolve from the repo root in code.

Getting Started

  1. Copy .env.example to .env and fill in the secrets.
  2. Open the repo in VS Code → "Reopen in Container". Setup installs dependencies and syncs backend/flows/; the entrypoints migrate and serve automatically.
  3. The stack is already running: UI at http://localhost:3000, API docs at http://localhost:8000/api/docs.

Development

Backend (attached api container, from backend/):

  • uv run pytest — full test suite (throwaway SQLite file, no external DB).
  • uv run alembic upgrade head — migrate the dev database.
  • uv run python scripts/sync_flows.py --sync — reconcile backend/flows/.
  • uv run python scripts/sync_flows.py --pull — export all Langflow flows into backend/flows/ first.
  • uv run python scripts/deploy_flow.py --langflow-id <uuid> — import one Langflow flow via the API.
  • uv run python scripts/make_flow_fixtures.py — regenerate the bundled flows (writes test fixtures and backend/flows/).
  • uv run python scripts/smoke_e2e.py — manual end-to-end smoke.

Frontend (node lives in the frontend container):

  • docker compose exec frontend npm run dev — HMR dev server (already running via compose; this is for a second instance or flags).
  • docker compose exec frontend npm run build — typecheck + build.
  • Without a docker socket: VS Code "Attach to Running Container" → frontend.

Flow workflow: design in Langflow → export into backend/flows/<name>.json (--pull, or UI download) → commit → the watcher deploys it automatically. Deleting a file removes the flow including its runs (git keeps the JSON).

Production (self-hosted, internal use — no TLS/reverse proxy included)

  1. Check out the repo on the host, create .env from .env.example with real secrets and FRONTEND_MODE=preview.
  2. docker compose up -d --build.
  3. Code updates via git pull + docker compose restart api frontend (the checkout is bind-mounted); image rebuilds only for dependency changes (docker compose up -d --build).

Container updates: registry images (langflowai/langflow:latest) auto-update nightly via Watchtower (nickfedor/watchtower). Locally built images (api, lfx, frontend) update with docker compose build --pull.

Continuous integration

Workflows in .forgejo/workflows/ run on Forgejo: backend pytest, frontend build, compose validation. They need a Runner with the docker label online (repo Settings → Actions → Runners) and action resolution for actions/checkout (github proxy or code.forgejo.org mirror).