Plan Checker, Wochenbericht-Fokus-Modus und Wandtafel-Dashboard-Feinschliff

Plan Checker (neues Studenten-Werkzeug, Seitenleiste + Admin → Plan-Checker-
Merkmale): lädt einen Bauplan als PDF hoch und lässt ChatGPT oder Claude ihn
gegen eine gepflegte Merkmalsliste prüfen. PDF-Rendering (pdf.js +
@napi-rs/canvas) berücksichtigt jetzt Ebenen (Optional Content Groups) und
WASM-Decoder korrekt, sendet eine Übersicht plus mehrere hochaufgelöste
Kachel-Ausschnitte statt eines einzelnen, zu groben Bilds, und beide Anbieter
bekommen dasselbe Bildmaterial. Jedes Prüfergebnis kann auf eines der
gesendeten Bilder als Beleg verweisen (bildIndex) — als Screenshot im
Ergebnis anklickbar, öffnet vergrößert in einem Modal statt eines von Chrome
blockierten target=_blank-Links auf eine data:-URL. KI-Modellname ist jetzt
pro Konto überschreibbar (Einstellungen → Mein Konto) für Drittanbieter mit
abweichendem Modell-Katalog.

Wochenbericht: dichte Kartenansicht bekommt einen Fokus-Modus — nur der
Kommentar liegt offen, Leistungsphasen und Beteiligte stecken in
aufklappbaren Abschnitten statt dauerhaft nebeneinander zu stehen.

Projektbereich: Terminplan-Auslastung rechnet jetzt exakt wie der
Auslastungs-Tab/die Wandtafel (statt einer unabhängigen, tageweisen
Schätzung); die LPH-Fortschrittsliste im Dashboard zeigt nur noch die
beauftragten Leistungsphasen.

Wandtafel: Dashboard-Kopf mit Kennzahlen-Reihe und Panel-Reihe neu
strukturiert, in den Blautönen des Firmenlogos; dieselbe Palette wurde
anschließend auf den gesamten App-weiten Dark Mode übernommen.

Dateibereinigung: nicht mehr benötigte Test-Uploads/Backups entfernt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
erikandClaude Sonnet 5 committed 2026-10-05 14:01:41 +02:00
1 parent db63a29365
commit 6ba93b2a92
308 files changed
+64441 -743

No files matched your search

+110
View File
@@ -0,0 +1,110 @@
'use strict'
const Dispatcher = require('./dispatcher')
const { InvalidArgumentError } = require('../core/errors')
const { toRawHeaders } = require('../core/util')
const { kOriginless, kUrl } = require('../core/symbols')
class LegacyHandlerWrapper {
#handler
constructor (handler) {
this.#handler = handler
}
onRequestStart (controller, context) {
this.#handler.onConnect?.((reason) => controller.abort(reason), context)
}
onRequestUpgrade (controller, statusCode, headers, socket) {
const rawHeaders = controller?.rawHeaders ?? toRawHeaders(headers ?? {})
this.#handler.onUpgrade?.(statusCode, rawHeaders, socket)
}
onResponseStart (controller, statusCode, headers, statusMessage) {
const rawHeaders = controller?.rawHeaders ?? toRawHeaders(headers ?? {})
if (this.#handler.onHeaders?.(statusCode, rawHeaders, () => controller.resume(), statusMessage) === false) {
controller.pause()
}
}
onResponseData (controller, chunk) {
if (this.#handler.onData?.(chunk) === false) {
controller.pause()
}
}
onResponseEnd (controller, trailers) {
const rawTrailers = controller?.rawTrailers ?? toRawHeaders(trailers ?? {})
this.#handler.onComplete?.(rawTrailers)
}
onResponseError (_controller, err) {
if (!this.#handler.onError) {
throw err
}
this.#handler.onError(err)
}
onBodySent (chunk) {
this.#handler.onBodySent?.(chunk)
}
onRequestSent () {
this.#handler.onRequestSent?.()
}
onResponseStarted () {
this.#handler.onResponseStarted?.()
}
}
class Dispatcher1Wrapper extends Dispatcher {
#dispatcher
constructor (dispatcher) {
super()
if (!dispatcher || typeof dispatcher.dispatch !== 'function') {
throw new InvalidArgumentError('Argument dispatcher must implement dispatch')
}
this.#dispatcher = dispatcher
this[kUrl] = dispatcher[kUrl]
this[kOriginless] = dispatcher[kOriginless]
}
static wrapHandler (handler) {
if (!handler || typeof handler !== 'object') {
throw new InvalidArgumentError('handler must be an object')
}
if (typeof handler.onRequestStart === 'function') {
return handler
}
return new LegacyHandlerWrapper(handler)
}
dispatch (opts, handler) {
// Legacy (v1) consumers do not support HTTP/2, so force HTTP/1.1.
// See https://github.com/nodejs/undici/issues/4989
if (opts.allowH2 !== false) {
opts = { ...opts, allowH2: false }
}
return this.#dispatcher.dispatch(opts, Dispatcher1Wrapper.wrapHandler(handler))
}
close (...args) {
return this.#dispatcher.close(...args)
}
destroy (...args) {
return this.#dispatcher.destroy(...args)
}
}
module.exports = Dispatcher1Wrapper