Replace vergabe's blue brand-* palette with whynot's near-black/paper/yellow
visual language. Tokens vendored at static/src/vendor/whynot-design/ (synced
from commit 9419f16 via scripts/sync-whynot-design.sh / make sync-whynot-design).
main.css imports the vendored CSS first, exposes ink/paper/hi as Tailwind
@theme tokens (bg-paper, text-ink, border-line, etc.), and re-tones every
component class (.btn-*, .card, .field-row, .phase-*, .form-input, .table-*,
.sidebar-*). Border radii drop to whynot's 0-4px; .card loses its shadow.
Legacy text-brand-* / bg-brand-* / border-brand-* template references are
kept working via @theme aliases that map the old blue scale onto the whynot
ink ramp — Phase 1 is tokens-only, no template churn.
btn-danger keeps an off-spec red (#B22222) as a local --danger var until
upstream defines a canonical destructive color.
base.html body class swapped: bg-slate-50 → bg-paper-2 text-ink.
Phase 2 (component adoption) deferred until whynot-design ships Lit web
components + missing atoms (Card, Modal, Input, Table, Toast). See
wiki/DesignSystem.md and history/2026-05-23-whynot-design-cross-framework-analysis.md.
Verified: 8/8 e2e tests pass; dev server boots; static/dist/main.css contains
no #3b5bdb references. Visual pixel-level verification still pending Bernd's
browser walk.
prod.py never read the CSRF_TRUSTED_ORIGINS env var the deployment already
injects, so Django's setting stayed empty. Behind traefik's TLS termination
Django saw requests as HTTP and rejected the browser's https:// Origin on
every POST with a CSRF failure (403) — forms could not be saved and the DB
stayed empty.
- Read CSRF_TRUSTED_ORIGINS from env (filtering empties).
- Set SECURE_PROXY_SSL_HEADER so Django recognizes HTTPS via X-Forwarded-Proto.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
issue-facade was renamed to issue-core. Update the dependency
declaration and the three Python imports it touched. Model field
names (issue_facade_backend, issue_facade_id) and the Django setting
ISSUE_FACADE_LOCAL_DB stay as-is — they are persisted/semantic
identifiers, not part of the package wiring.
All 20 aufgaben tests pass after the rewire.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Aufgabe.erstellt_am für implizite 7-Tage-Fälligkeit
- frist_effektiv property; ist_ueberfaellig nutzt sie
- AufgabenVerknuepfung (GenericForeignKey) mit HTMX-Panel
- ExternalIssue (OneToOne) mit IssueAdapter-ABC und HTMX-Panel
- link_registry.py und issue_facade.py als zentrale Registries
- 8 neue Tests, 76 gesamt grün
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Im globalen /aufgaben/-Kontext ist ausschreibung=None; die direkten FK-IDs
auf dem Aufgabe-Objekt sind immer vorhanden und erfordern kein Queryset-Join.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Aufgaben sind jetzt direkt von der Detailseite erreichbar und anlegbar:
- Aufgaben-Panel mit HTMX-Inline-Formular auf ausschreibung_detail
- Globaler Sidebar-Link /aufgaben/ für ausschreibungsübergreifende Übersicht
- aufgaben-Queryset in ausschreibung_detail-Kontext ergänzt
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Aufgabe bekommt ein phase-Feld (1–8). aufgaben_score()-Helper in
core/services.py berechnet abgeschlossen/total/score_pct für jedes
QuerySet. Score-Spalten in Ausschreibungen-Liste, Lose-Liste und
Ausschreibungs-Detail; per-Phase-Scores in der Seitenleisten-Navigation.
Phasenfilter in Aufgaben-Liste. 68 Tests grün.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replaced broken status_aendern (missing status_choices in response)
with a single eintrag_bearbeiten view that always returns the full
partial context
- eintrag_zeile.html is now a <tbody x-data="{ editing: false }"> with
two rows: display row + collapsible edit form
- Click anywhere on a row to expand the edit form; @click.stop on the
status cell prevents accidental toggles
- Status dropdown in the display row posts via HTMX and swaps the whole
<tbody> — no page reload needed
- Edit form covers all fields: titel, beschreibung, kategorie,
dringlichkeit, status, bewertung, entscheidung
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The submit endpoint only accepts POST; the sidebar was pointing to it
causing a 405 on click.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implementiert Subunternehmer-Katalog mit Suche/Filter, Zuordnung zu Losen via HTMX-Modal,
Dienstleistertyp-CRUD und Präferenz-Badges. Bibliothek: Nachweis-Katalog mit Ablaufwarnung
und Versionierung, Referenz-Katalog mit Ausschreibungszuordnung, Leistungsblatt-CRUD,
Entscheidungsregel-CRUD mit Aktiv-Toggle. Migration für referenzen M2M auf Ausschreibung.
56 Tests grün. Tests-Discovery auf tests.py-Dateien ausgedehnt.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Vollständigkeitsprüfung mit Freigaben-Check, Abgabe dokumentieren mit
Nachweis-Upload, Nachbetrachtung mit Kickoff-Aufgabe (gewonnen) und
Alpine.js-gesteuerter Verlustanalyse (verloren). 5 Tests grün.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>