feat: initial project setup

- FastAPI backend (Python 3.12, uv)
- React 19 + TypeScript + Vite frontend
- Devcontainer with Node 22, Python 3.12, uv, opencode
- Basic app structure and project docs
This commit is contained in:
Jonas Miederer 2026-09-04 10:17:22 +00:00
commit 418318152a
20 changed files with 2324 additions and 0 deletions

43
.devcontainer/Dockerfile Normal file
View file

@ -0,0 +1,43 @@
FROM mcr.microsoft.com/devcontainers/base:debian
ARG FORGEJO_USERNAME
ENV FORGEJO_USERNAME=${FORGEJO_USERNAME}
# SSH (missing from base image)
RUN apt-get update \
&& apt-get install -y --no-install-recommends openssh-client \
&& rm -rf /var/lib/apt/lists/*
# Node.js 22 + npm (npm tree copied; bin symlinks recreated - COPY dereferences them)
COPY --from=node:22-slim /usr/local/bin/node /usr/local/bin/
COPY --from=node:22-slim /usr/local/lib/node_modules /usr/local/lib/node_modules
RUN ln -s ../lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \
&& ln -s ../lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx
# uv (from distroless)
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
# Python 3.12 (system-shared location; default /root is unreadable for vscode)
ENV UV_PYTHON_INSTALL_DIR=/opt/uv/python
RUN uv python install 3.12 \
&& ln -s /opt/uv/python/cpython-3.12-linux-x86_64-gnu/bin/python3.12 /usr/local/bin/python3.12 \
&& ln -s python3.12 /usr/local/bin/python3 \
&& ln -s python3 /usr/local/bin/python
# Trust the workspace bind mount (source on Windows FS -> uid mismatch)
RUN git config --system --add safe.directory /workspaces/kirche-einfach
# Pre-create named-volume targets (volumes inherit image content on first mount)
RUN mkdir -p /workspaces/kirche-einfach/backend/.venv \
/workspaces/kirche-einfach/frontend/node_modules
# opencode (as non-root user)
USER vscode
RUN curl -fsSL https://opencode.ai/install | bash
USER root
RUN ln -s /home/vscode/.opencode/bin/opencode /usr/local/bin/opencode
# Fix ownership (home + volume targets so vscode user can write)
RUN chown -R vscode:vscode /home/vscode /workspaces
CMD ["sleep", "infinity"]

View file

@ -0,0 +1,36 @@
{
"name": "kirche-einfach",
"build": {
"dockerfile": "Dockerfile",
"args": {
"FORGEJO_USERNAME": "jonas"
}
},
"mounts": [
"source=${localEnv:USERPROFILE}/.ssh,target=/mnt/host-ssh,type=bind,readonly",
"source=kirche-einfach-venv,target=/workspaces/kirche-einfach/backend/.venv,type=volume",
"source=kirche-einfach-node-modules,target=/workspaces/kirche-einfach/frontend/node_modules,type=volume"
],
"remoteUser": "vscode",
"containerEnv": {
"FORGEJO_USERNAME": "jonas"
},
"overrideCommand": false,
"workspaceFolder": "/workspaces/kirche-einfach",
"postCreateCommand": "sudo -E bash .devcontainer/setup.sh",
"postStartCommand": "mkdir -p ~/.ssh && cp /mnt/host-ssh/id_rsa /mnt/host-ssh/id_rsa.pub ~/.ssh/ && cp /mnt/host-ssh/known_hosts ~/.ssh/ 2>/dev/null; ssh-keyscan -t ed25519,rsa gitlab.jonas-miederer.com >> ~/.ssh/known_hosts 2>/dev/null; chmod 700 ~/.ssh && chmod 600 ~/.ssh/id_rsa && chmod 644 ~/.ssh/id_rsa.pub ~/.ssh/known_hosts",
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"charliermarsh.ruff",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode"
],
"settings": {
"python.defaultInterpreterPath": "/workspaces/kirche-einfach/backend/.venv/bin/python"
}
}
}
}

23
.devcontainer/setup.sh Normal file
View file

@ -0,0 +1,23 @@
#!/bin/bash
set -e
echo "=== Setting up kirche-einfach ==="
# Backend
echo "--- Installing Python dependencies ---"
cd /workspaces/kirche-einfach/backend
uv sync
# Frontend
echo "--- Installing Node dependencies ---"
cd /workspaces/kirche-einfach/frontend
npm install
echo ""
echo "=== Setup complete ==="
echo "Forgejo username: $FORGEJO_USERNAME"
# Hand dirs back to vscode (this script runs via sudo; uv/npm create caches as root)
chown -R vscode:vscode /workspaces/kirche-einfach/backend/.venv \
/workspaces/kirche-einfach/frontend/node_modules \
/home/vscode/.cache 2>/dev/null || true

27
.gitignore vendored Normal file
View file

@ -0,0 +1,27 @@
# Python
__pycache__/
*.py[cod]
*.egg-info/
.venv/
*.egg
# Node
node_modules/
dist/
# Environment
.env
.env.local
# IDE
.vscode/
.idea/
*.swp
*.swo
# OS
.DS_Store
Thumbs.db
# uv
uv.lock

17
README.md Normal file
View file

@ -0,0 +1,17 @@
# Kirche Einfach
KI-gestützte Verwaltungsplattform für Kirche.
## Stack
- **Backend:** Python 3.12, FastAPI, Django, uv
- **Frontend:** React 19, TypeScript, Vite
- **Dev:** Devcontainer, opencode
## Getting Started
Open in VS Code → "Reopen in Container".
Backend: `http://localhost:8000`
Frontend: `http://localhost:3000`
API Docs: `http://localhost:8000/api/docs`

1
backend/.python-version Normal file
View file

@ -0,0 +1 @@
3.12

0
backend/app/__init__.py Normal file
View file

22
backend/app/main.py Normal file
View file

@ -0,0 +1,22 @@
from fastapi import FastAPI
from .settings import settings
app = FastAPI(
title="Kirche Einfach API",
description="KI-gestützte Verwaltungsplattform für Kirche",
version="0.1.0",
docs_url="/api/docs",
redoc_url="/api/redoc",
openapi_url="/api/openapi.json",
)
@app.get("/")
async def root():
return {"message": "Kirche Einfach API", "version": settings.version}
@app.get("/health")
async def health():
return {"status": "ok"}

11
backend/app/settings.py Normal file
View file

@ -0,0 +1,11 @@
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
version: str = "0.1.0"
debug: bool = False
model_config = {"env_prefix": "KIRCHE_"}
settings = Settings()

19
backend/pyproject.toml Normal file
View file

@ -0,0 +1,19 @@
[project]
name = "kirche-einfach-backend"
version = "0.1.0"
description = "Kirche Einfach - KI-gestuetzte Verwaltungsplattform fuer Kirche"
requires-python = ">=3.12"
dependencies = [
"fastapi[standard]>=0.115.0",
"django>=5.1",
"pydantic-settings>=2.0",
"uvicorn[standard]>=0.30.0",
]
[build-system]
requires = ["uv_build>=0.12.3,<0.13"]
build-backend = "uv_build"
[tool.uv.build-backend]
module-name = "app"
module-root = ""

View file

12
frontend/index.html Normal file
View file

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Kirche Einfach</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>

1841
frontend/package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

22
frontend/package.json Normal file
View file

@ -0,0 +1,22 @@
{
"name": "kirche-einfach-frontend",
"private": true,
"version": "0.1.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"preview": "vite preview"
},
"dependencies": {
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"@vitejs/plugin-react": "^4.3.0",
"typescript": "~5.6.0",
"vite": "^6.0.0"
}
}

10
frontend/src/App.tsx Normal file
View file

@ -0,0 +1,10 @@
function App() {
return (
<div>
<h1>Kirche Einfach</h1>
<p>KI-gestützte Verwaltungsplattform für Kirche</p>
</div>
);
}
export default App;

9
frontend/src/main.tsx Normal file
View file

@ -0,0 +1,9 @@
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App";
createRoot(document.getElementById("root")!).render(
<StrictMode>
<App />
</StrictMode>,
);

20
frontend/tsconfig.json Normal file
View file

@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2023", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true
},
"include": ["src"]
}

15
frontend/vite.config.ts Normal file
View file

@ -0,0 +1,15 @@
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
server: {
port: 3000,
proxy: {
"/api": {
target: "http://localhost:8000",
changeOrigin: true,
},
},
},
});

3
opencode.json Normal file
View file

@ -0,0 +1,3 @@
{
"$schema": "https://opencode.ai/config.json"
}

193
transkript_ideen.md Normal file
View file

@ -0,0 +1,193 @@
## Kopfbereich
**Kirche Einfach.**
Verwaltung. Einfach. Sicher.
**Die intelligente Verwaltungsplattform für Kirche.**
Fragen. Verstehen. Prüfen. Genehmigen. Erledigt.
Eine KI-gestützte Plattform, die kirchliche Verwaltungsprozesse vereinfacht.
Wissen bereitstellt und Routine automatisiert – sicher, regelbasiert und nachvollziehbar.
### Unser Ziel
Mehr Zeit für das Wesentliche.
Weniger Aufwand für Verwaltung.
***
## Linke Textbox: So einfach funktioniert es
### 1. Anliegen stellen
Sie beschreiben Ihr Anliegen in eigenen Worten.
„Wir wollen das Dach unseres Gemeindehauses für 120.000 € sanieren.“
### 2. KI versteht & berät
Unsere Wissens-KI erklärt, was zu beachten ist und welche Schritte erforderlich sind.
### 3. Prozess starten
Die KI führt Sie durch den Prozess, stellt Fragen und sammelt alle notwendigen Informationen.
### 4. Prüfen & automatisieren
Dokumente werden ausgelesen, Regeln geprüft und der Vorgang automatisiert bearbeitet.
### 5. Entscheiden & abschließen
Standardfälle werden automatisch freigegeben. Bei Auffälligkeiten prüft ein Sachbearbeiter. Der Vorgang wird dokumentiert.
***
## Zentrale Textbox: Ein Portal – alle Verwaltungsprozesse
### Navigation
- Start
- Meine Vorgänge
- Aufgaben
- Wissen & Hilfe
- Dashboard
### Aufgabenanzeige
7
### Eingabefeld
Was möchten Sie erledigen?
Fragen Sie mich etwas ...
### Verwaltungsbereiche
- Bauen & Immobilien
- Personal
- Haushalt & Finanzen
- Beschaffung & Vergabe
- Zuschüsse & Fördermittel
- Gremien & Beschlüsse
- Recht & Genehmigungen
- Wissen & Vorschriften
***
## Zentrale Textbox: Unsere KI-Plattform – sicher & regelbasiert
### Wissens-KI
Antworten mit Quellen aus Kirchenrecht, Rundschreiben, Dienstanweisungen und FAQ.
### Prozessassistent
Versteht Ihr Anliegen und führt Sie Schritt für Schritt durch den Prozess.
### Dokumenten-KI
Liest, versteht und extrahiert Daten aus PDFs, E-Mails und Belegen.
### Regelengine
Prüft automatisch Regeln, Schwellenwerte, Zuständigkeiten und Vollständigkeit.
### Workflow & Entscheidung
Standardfall: automatisch
Sonderfall: gezielte menschliche Prüfung
***
## Textbox: Integration in Ihre Systeme
- Finanzbuchhaltung
- Personalwesen
- DMS / Archiv
- Kirchenbuch / Meldewesen
- Microsoft 365
- Weitere Fachverfahren
***
## Rechte Textbox: Ausnahmeverwaltung statt Vollprüfung
### Standardfall
Alle Regeln erfüllt.
Automatischer Workflow bis zur Freigabe.
### Auffälliger Fall
Kleine Abweichungen oder Unklarheiten.
Gezielte Prüfung durch Sachbearbeiter.
### Risiko-/Sonderfall
Rechtlich oder finanziell kritisch.
Vollständige Fachprüfung erforderlich.
***
## Rechte Textbox: Ihr Nutzen
### Zeit sparen
Bis zu 70% weniger Bearbeitungszeit bei Routinevorgängen.
### Mitarbeiter entlasten
Weniger manuelle Prüfungen, mehr Zeit für Menschen und Ausnahmen.
### Rechtssicher & nachvollziehbar
Jede Entscheidung basiert auf Regeln und ist revisionssicher dokumentiert.
### Wissen nutzen
Zentralisiertes Wissen macht Vorschriften, Zuständigkeiten und Prozesse für alle zugänglich.
### Steuern & planen
Echtzeit-Übersichten für Leitung und Verwaltung – bessere Entscheidungen.
***
## Untere Textbox: Darauf können Sie sich verlassen
### Datenschutz & Sicherheit
DSG-EKD / DSGVO-konform,
Hosting in Deutschland,
höchste Sicherheitsstandards.
### Mensch im Mittelpunkt
KI unterstützt, der Mensch entscheidet. Jederzeit eingreifbar.
### Transparenz
Jede Antwort mit Quelle.
Jede Prüfung ist erklärbar und nachvollziehbar.
### Flexibel & integrierbar
Offene Schnittstellen.
Anbindung an bestehende Systeme.
### Mehr Zeit für das Wesentliche.
Wir kümmern uns um den Aufwand.
***
## Untere rechte Textbox: Beispiele aus der Praxis
- Bauvorhaben bis 200.000 € prüfen & genehmigen
- Personaleinstellungen automatisieren
- Haushaltsentwurf erstellen & plausibilisieren
- Zuschussanträge prüfen & bescheiden
- Beschaffungen bis zur Vergabe freigeben
- und vieles mehr ..