This commit is contained in:
breitenbach76 2026-06-09 07:28:37 +02:00
parent de433773b7
commit 6e1bc8d944
31 changed files with 53 additions and 22 deletions

Binary file not shown.

View file

@ -34,9 +34,15 @@ LET_SIZE, LET_DEP = 11.0, 1.0
WORD_SIZE, WORD_DEP = 5.0, 0.8 WORD_SIZE, WORD_DEP = 5.0, 0.8
TOP = BASE_H TOP = BASE_H
HERE = os.path.dirname(bpy.data.filepath) or os.path.dirname(os.path.abspath(__file__)) def _outdir():
d = os.path.dirname(bpy.data.filepath) # gesetzt, wenn .blend gespeichert
if d: return d
try: return os.path.dirname(os.path.abspath(__file__))
except NameError: return os.path.expanduser("~") # Fallback: Benutzerordner
HERE = _outdir()
STL_OUT = os.path.join(HERE, "raci-board.stl") STL_OUT = os.path.join(HERE, "raci-board.stl")
PNG_OUT = os.path.join(HERE, "raci_preview.png") PNG_OUT = os.path.join(HERE, "raci_preview.png")
print("Ausgabe-Ordner:", HERE)
# ----------------------------- Helfer ----------------------------- # ----------------------------- Helfer -----------------------------
def clear_scene(): def clear_scene():
@ -149,27 +155,44 @@ cut_text(base, "INFORMED", DIAL_CX, DIAL_CY-(RING_R+30), 0, WORD_SIZE, WORD_DEP)
cut_text(base, "ACCOUNTABLE", DIAL_CX, CARD_CY - CARD_BD/2 - 8, 0, WORD_SIZE, WORD_DEP) cut_text(base, "ACCOUNTABLE", DIAL_CX, CARD_CY - CARD_BD/2 - 8, 0, WORD_SIZE, WORD_DEP)
base.name = "RACI-Board" base.name = "RACI-Board"
bpy.ops.object.shade_smooth() # Auto-Smooth: flache Flaechen scharf, gefaste Kanten glatt
try:
bpy.ops.object.shade_auto_smooth(angle=math.radians(30)) # Blender >= 4.1
except Exception:
try: bpy.ops.object.shade_flat()
except Exception: pass
# ----------------------------- Material ----------------------------- # ----------------------------- Material -----------------------------
mat = bpy.data.materials.new("BoardBlue"); mat.use_nodes = True mat = bpy.data.materials.new("BoardBlue"); mat.use_nodes = True
bsdf = mat.node_tree.nodes.get("Principled BSDF") bsdf = next((n for n in mat.node_tree.nodes if n.type == 'BSDF_PRINCIPLED'), None)
if bsdf: if bsdf:
bsdf.inputs["Base Color"].default_value = (0.10, 0.16, 0.30, 1) bsdf.inputs["Base Color"].default_value = (0.09, 0.15, 0.30, 1) # dunkelblau
try: bsdf.inputs["Roughness"].default_value = 0.55 try: bsdf.inputs["Roughness"].default_value = 0.5
except Exception: pass except Exception: pass
base.data.materials.append(mat) base.data.materials.clear(); base.data.materials.append(mat)
# ----------------------------- Vorschau-Render (guarded) ----------------------------- # ----------------------------- Vorschau-Render (guarded) -----------------------------
try: try:
bpy.ops.object.light_add(type='SUN', location=(120, -160, 220))
bpy.context.object.data.energy = 3.0
bpy.ops.object.camera_add(location=(150, -190, 210))
cam = bpy.context.object
cam.rotation_euler = (math.radians(58), 0, math.radians(38))
bpy.context.scene.camera = cam
sc = bpy.context.scene sc = bpy.context.scene
sc.render.resolution_x, sc.render.resolution_y = 1400, 1000 # Welt etwas aufhellen
try:
wn = sc.world.node_tree.nodes
bg = next((n for n in wn if n.type == 'BACKGROUND'), None)
if bg: bg.inputs[1].default_value = 1.2
except Exception: pass
# Licht
bpy.ops.object.light_add(type='SUN', location=(120, -160, 240))
bpy.context.object.data.energy = 3.5
bpy.ops.object.light_add(type='AREA', location=(-120, -60, 160))
bpy.context.object.data.energy = 4000; bpy.context.object.data.size = 200
# Kamera blickt aufs Board-Zentrum (Track-To), rahmt das ganze Board
bpy.ops.object.empty_add(location=(0, 0, 4)); tgt = bpy.context.object
bpy.ops.object.camera_add(location=(175, -220, 210)); cam = bpy.context.object
cam.data.lens = 52
con = cam.constraints.new('TRACK_TO'); con.target = tgt
con.track_axis = 'TRACK_NEGATIVE_Z'; con.up_axis = 'UP_Y'
sc.camera = cam
sc.render.resolution_x, sc.render.resolution_y = 1500, 1050
sc.render.filepath = PNG_OUT sc.render.filepath = PNG_OUT
try: sc.render.engine = 'BLENDER_EEVEE_NEXT' try: sc.render.engine = 'BLENDER_EEVEE_NEXT'
except Exception: except Exception:

Binary file not shown.

After

Width:  |  Height:  |  Size: 813 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 116 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

After

Width:  |  Height:  |  Size: 130 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 103 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

After

Width:  |  Height:  |  Size: 134 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 106 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 201 KiB

After

Width:  |  Height:  |  Size: 201 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 98 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 147 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

After

Width:  |  Height:  |  Size: 136 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 112 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 KiB

After

Width:  |  Height:  |  Size: 179 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

After

Width:  |  Height:  |  Size: 109 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

After

Width:  |  Height:  |  Size: 119 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 89 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 KiB

After

Width:  |  Height:  |  Size: 182 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

After

Width:  |  Height:  |  Size: 114 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

After

Width:  |  Height:  |  Size: 193 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

After

Width:  |  Height:  |  Size: 116 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 111 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 KiB

After

Width:  |  Height:  |  Size: 155 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 100 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB

After

Width:  |  Height:  |  Size: 188 KiB

Before After
Before After

View file

@ -407,7 +407,7 @@ const PHASEN = {
support:{label:"Support", color:"var(--support)"}, support:{label:"Support", color:"var(--support)"},
review:{label:"Review", color:"var(--review)"} review:{label:"Review", color:"var(--review)"}
}; };
/* Action Cards: 6 Services × 5 Change-Typen (aus „Use Cases mit möglichen Changes"). */ /* Action Cards: 6 Services × 4 Change-Arten (aus „Use Cases mit möglichen Changes"). */
const CHANGE_TYPES = [ const CHANGE_TYPES = [
"Major Change", "Major Change",
"Normal Change", "Normal Change",
@ -499,7 +499,7 @@ const USE_CASES = [
desc:"Zentrales Web-Portal, über das Bürger*innen Meldungen (z. B. Straßenreparatur, Lärm) und Anträge (z. B. Baugenehmigung, Personalausweis) digital einreichen und den Status verfolgen.", desc:"Zentrales Web-Portal, über das Bürger*innen Meldungen (z. B. Straßenreparatur, Lärm) und Anträge (z. B. Baugenehmigung, Personalausweis) digital einreichen und den Status verfolgen.",
changes:[ changes:[
{titel:"Mitreden, Pflicht!", text:"Ein neues Landesgesetz schreibt digitale Bürgerbeteiligung vor — das Portal muss um komplette Beteiligungs-Module erweitert werden."}, {titel:"Mitreden, Pflicht!", text:"Ein neues Landesgesetz schreibt digitale Bürgerbeteiligung vor — das Portal muss um komplette Beteiligungs-Module erweitert werden."},
{titel:"Rotstift gefragt", text:"Der Bürgerservice meldet einen Rechtschreibfehler in einem statischen Hinweistext, der korrigiert werden muss."}, {titel:"Licht an!", text:"Das Amt für öffentliche Ordnung möchte eine neue Mängel-Kategorie „Beleuchtung und Strom“ zu den bestehenden Kategorien hinzufügen."},
{titel:"Patchday", text:"Das monatliche Sicherheits-Patch des Webservers (Apache/Nginx) steht an."}, {titel:"Patchday", text:"Das monatliche Sicherheits-Patch des Webservers (Apache/Nginx) steht an."},
{titel:"Lücke im Formular!", text:"In einem Eingabe-Formular wird eine kritische XSS-Schwachstelle entdeckt — ein Hotfix muss sofort raus."} {titel:"Lücke im Formular!", text:"In einem Eingabe-Formular wird eine kritische XSS-Schwachstelle entdeckt — ein Hotfix muss sofort raus."}
]}, ]},
@ -515,7 +515,7 @@ const USE_CASES = [
desc:"Web-basiertes Karten- und Analyse-Portal, das Fachämtern (Bau, Umwelt, Verkehr) räumliche Daten (Flurstücke, Infrastruktur, Umweltzonen) und bearbeitbare Layer bereitstellt.", desc:"Web-basiertes Karten- und Analyse-Portal, das Fachämtern (Bau, Umwelt, Verkehr) räumliche Daten (Flurstücke, Infrastruktur, Umweltzonen) und bearbeitbare Layer bereitstellt.",
changes:[ changes:[
{titel:"Norm-Zwang", text:"Eine bundesweite Vorgabe zu EU-Standards erzwingt die komplette Migration des GIS-Stacks auf konforme Services und Datenmodelle."}, {titel:"Norm-Zwang", text:"Eine bundesweite Vorgabe zu EU-Standards erzwingt die komplette Migration des GIS-Stacks auf konforme Services und Datenmodelle."},
{titel:"Falsch beschriftet", text:"Das Bauamt meldet eine falsche Beschriftung eines Karten-Layers, die korrigiert werden muss."}, {titel:"Grün dazu!", text:"Das Umweltamt möchte im Analyse-Modul „Klimarisiko-Analyse“ eine weitere Datenquelle zu städtischen Grünflächen anbinden."},
{titel:"GeoServer-Update", text:"Das monatliche Update der GIS-Software (GeoServer 2.23 → 2.24) steht an."}, {titel:"GeoServer-Update", text:"Das monatliche Update der GIS-Software (GeoServer 2.23 → 2.24) steht an."},
{titel:"Schnittstelle offen!", text:"An einer Schnittstelle wird eine kritische Schwachstelle entdeckt, die unautorisierten Datenzugriff erlaubt — Dienst sofort abschalten und patchen."} {titel:"Schnittstelle offen!", text:"An einer Schnittstelle wird eine kritische Schwachstelle entdeckt, die unautorisierten Datenzugriff erlaubt — Dienst sofort abschalten und patchen."}
]}, ]},
@ -523,7 +523,7 @@ const USE_CASES = [
desc:"Web-Applikation, über die Fachämter interne Beschaffungen (Material, Dienstleistungen) anlegen, prüfen und Verträge digital verwalten.", desc:"Web-Applikation, über die Fachämter interne Beschaffungen (Material, Dienstleistungen) anlegen, prüfen und Verträge digital verwalten.",
changes:[ changes:[
{titel:"Vergabe neu!", text:"Eine neue EU-Vergaberichtlinie zwingt zur Einführung von E-Invoicing und erweiterten Transparenz-Reports."}, {titel:"Vergabe neu!", text:"Eine neue EU-Vergaberichtlinie zwingt zur Einführung von E-Invoicing und erweiterten Transparenz-Reports."},
{titel:"Vierstellig, bitte", text:"Das Finanzamt wünscht eine kleine Anpassung: aus dem Label „Kostenstelle“ wird „Kostenstelle (4-stellig)“."}, {titel:"Format-Wechsel", text:"Die Verträge der Fachämter liegen wegen aktualisierter Sicherheitsrichtlinien in einem neuen Dateiformat vor — die Schnittstellen der Web-Applikation müssen entsprechend angepasst werden."},
{titel:"Patch-Quartal", text:"Das quartalsweise Sicherheits-Patch des Anwendungsservers steht an."}, {titel:"Patch-Quartal", text:"Das quartalsweise Sicherheits-Patch des Anwendungsservers steht an."},
{titel:"Upload-Falle!", text:"Im Vertrags-Upload wird eine kritische Lücke entdeckt, über die sich Schadcode hochladen lässt — Endpoint sofort sperren, Hotfix einspielen."} {titel:"Upload-Falle!", text:"Im Vertrags-Upload wird eine kritische Lücke entdeckt, über die sich Schadcode hochladen lässt — Endpoint sofort sperren, Hotfix einspielen."}
]} ]}
@ -1119,7 +1119,7 @@ function cardHtml(si, ci){ const c = acard(si, ci);
return `<div style="font-weight:800;font-size:18px;color:var(--ink);margin-bottom:6px">${c.titel}</div>` return `<div style="font-weight:800;font-size:18px;color:var(--ink);margin-bottom:6px">${c.titel}</div>`
+ `<div>${c.text}</div>` + `<div>${c.text}</div>`
+ `<div style="color:var(--muted);font-style:italic;margin-top:8px">Was passiert an welchen Stellen?</div>`; } + `<div style="color:var(--muted);font-style:italic;margin-top:8px">Was passiert an welchen Stellen?</div>`; }
// Finale Action-Card-Grafik (cards/s<service>-c<change>.png) — alle 30 vorhanden. // Finale Action-Card-Grafik (cards/s<service>-c<change>.png) — alle 24 vorhanden.
function cardImg(si, ci){ return `cards/s${si}-c${ci}.png`; } function cardImg(si, ci){ return `cards/s${si}-c${ci}.png`; }
function cardMedia(si, ci){ const f = cardImg(si, ci); function cardMedia(si, ci){ const f = cardImg(si, ci);
return f ? `<img class="acImg" src="${f}" alt="Action Card: ${acard(si,ci).titel}" return f ? `<img class="acImg" src="${f}" alt="Action Card: ${acard(si,ci).titel}"

View file

@ -1,7 +1,7 @@
/* Service Worker — SLC-Workshop Companion (App-Shell, offline-first) */ /* Service Worker — SLC-Workshop Companion (App-Shell, offline-first) */
const CACHE = "slc-companion-v21"; const CACHE = "slc-companion-v23";
const SHELL = ["./", "index.html", "manifest.webmanifest", "icon.svg"]; const SHELL = ["./", "index.html", "manifest.webmanifest", "icon.svg"];
// Action-Card-Grafiken (cards/s<service>-c<change>.png) fuer Offline vorab cachen (alle 30). // Action-Card-Grafiken (cards/s<service>-c<change>.png) fuer Offline vorab cachen (alle 24).
const CARDS = []; const CARDS = [];
for (let s = 0; s <= 5; s++) for (let c = 0; c <= 3; c++) { for (let s = 0; s <= 5; s++) for (let c = 0; c <= 3; c++) {
CARDS.push(`cards/s${s}-c${c}.png`); CARDS.push(`cards/s${s}-c${c}.png`);

View file

@ -115,8 +115,16 @@ Konzept (`00_Konzept/README_konzept.md`), bis Rückkopplung mit Michael:**
- [x] **„Verräter"-Sätze** aus 5 Standard-Karten raus (Quartalspflege, Monatsroutine, Patchday, - [x] **„Verräter"-Sätze** aus 5 Standard-Karten raus (Quartalspflege, Monatsroutine, Patchday,
GeoServer-Update, Patch-Quartal). GeoServer-Update, Patch-Quartal).
- [x] **Einstiegs-Frage** umformuliert: „Wo würde die Umsetzung starten (nach Freigabe)?". - [x] **Einstiegs-Frage** umformuliert: „Wo würde die Umsetzung starten (nach Freigabe)?".
- [ ] **Wartet auf Frank:** 3 „Normal"-Karten (Rotstift gefragt · Vierstellig, bitte · Falsch - [x] **3 „Normal"-Karten neu** (aus Franks Word v2, ehemals fälschlich Standard): `s2-c1`
beschriftet) sind eigentlich **Standard** → neue **Normal**-Texte aus Franks Word übernehmen. **„Licht an!"** (neue Mängel-Kategorie Beleuchtung/Strom) · `s4-c1` **„Grün dazu!"**
(Grünflächen-Datenquelle im Klimarisiko-Modul) · `s5-c1` **„Format-Wechsel"** (neues
Vertrags-Dateiformat → Schnittstellen anpassen). **Texte in `index.html` ersetzt.**
- [x] **Alle 24 Karten-Grafiken** durch das finale Canva-Set ersetzt (`SLC Actioncards`,
30 Karten → die 24 richtigen übernommen). Neue Normals (Licht an!/Grün dazu!/Format-Wechsel)
und bereinigte Standards (ohne „Katalog"-Satz) sind jetzt auch grafisch korrekt. Bild = Text.
**Nicht verwendet:** 6 „Major Low Level"-Extras (Bauamt will mehr! · Schlüsselpflicht ·
Ratsbeschluss! · Akten-Zuwachs · Klimarisiko im Blick · Portal für Partner) — App nutzt nur
einen Major (Top-Level) je Service. Liegen im Download-Ordner, falls später gewünscht.
- [ ] **Wartet auf Frank:** Service-Steckbrief-Beiblatt (6 Services: Was ist der Service, was der - [ ] **Wartet auf Frank:** Service-Steckbrief-Beiblatt (6 Services: Was ist der Service, was der
IT-Provider-Anteil) aus Franks Inhalten. IT-Provider-Anteil) aus Franks Inhalten.
- [ ] **Klären (Frank + Patrick):** **Problem-Manager**-Rolle — in App vorhanden (`sp_09/sp_10`), - [ ] **Klären (Frank + Patrick):** **Problem-Manager**-Rolle — in App vorhanden (`sp_09/sp_10`),