21 Commits

Author SHA1 Message Date
00469c4cc0 Adopt whynot-design tokens (WP-0017 Phase 1)
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.
2026-05-23 21:52:59 +02:00
f95de1482d Fix CSRF 403 on all POSTs behind traefik
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>
2026-05-22 02:02:42 +02:00
17f511fbcd Rewire issue tracker integration from issue-facade to issue-core
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>
2026-05-18 22:33:28 +02:00
a907ed6f74 issue-facade integration 2026-05-14 11:30:30 +02:00
816c281f6a feat(aufgaben): Verknüpfungen, implizite Fälligkeit, Issue-Facade (WP-0015)
- 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>
2026-05-14 04:18:28 +02:00
b054824862 fix(aufgaben): aufgabe_row.html nutzt aufgabe.ausschreibung_id statt ausschreibung.pk
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>
2026-05-14 03:17:14 +02:00
9ef6e0950a feat(aufgaben): Aufgaben-Panel auf Ausschreibungs-Detailseite + Sidebar-Link
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>
2026-05-14 03:12:23 +02:00
f6af101933 Unterstützung für Lose 2026-05-14 02:57:27 +02:00
e4eb5bc368 feat(WP-0014): Aufgaben-Phasenzuordnung und Fertigstellungs-Scores
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>
2026-05-14 01:47:05 +02:00
7903f59f85 fix(WP-0013): Feedback-Bugs — alle 8 Einträge aus Backlog behoben
- Fristen-Widget-Format: DateInput/DateTimeInput mit ISO-Format-Attribut, damit
  Browser date/datetime-local korrekt vorausfüllen (Feedback #4)
- Phase 2 Teilnahmeentscheidung: URL in build_phase_nav von
  /teilnahmeentscheidung/ → /entscheidung/ korrigiert (Feedback #6)
- Phase 3 Detaillierte Durchsicht: URL in build_phase_nav von
  /anforderungen/ → /lose/anforderungen/ korrigiert (Feedback #7)
- Phase 7 Abgabe: order_by('bezeichnung') → order_by('beschreibung') in
  abgabe_views.py (Dokument hat kein Feld 'bezeichnung') (Feedback #8)
- Ausschreibungen-Liste: Ausschreiber zuerst, Titel zweite Spalte,
  neues geschätztes Volumen (Feedback #5)
- Feedback-Backlog Leerstand: bereits durch vorherigen URL-Fix abgedeckt
  (Feedback #1)
- Rechtsgrundlage (VgV/UVgO/VOB/A/SektVO/GWB) als neues Formularfeld
  incl. Migration (Feedback #2)
- Bindefrist in Tagen + berechnetes Enddatum als Modell-Property
  bindefrist_berechnet, Formular und Detailansicht erweitert (Feedback #3)

68/68 Tests grün.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 00:31:55 +02:00
40e70e64f0 fix(feedback): inline edit + live status change without reload
- 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>
2026-05-13 23:45:10 +02:00
40739c1bfd fix(feedback): sidebar links to /feedback/backlog/ not /feedback/
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>
2026-05-13 23:35:22 +02:00
5a231223c0 feat(WP-0012): Querschnitt — Freigaben, Felder, Feedback, Suche, Tests
Implements all 8 tasks of the final cross-cutting workplan:

- T01: Generisches Freigabe-Modal (freigabe_modal, freigabe_erteilen views + templates)
- T02: Freigaben-Übersicht pro Ausschreibung (freigaben_uebersicht view + template)
- T03: EntityFieldConfig Admin-Interface (/felder/<entity_type>/ with HTMX toggle)
- T04: CustomAttribute-Panel (full CRUD with sort, lazy HTMX load)
- T05: Feedback-Backlog mit Statusverwaltung + feedback_success.html template
- T06: End-to-End-Tests in vergabe_teilnahme/tests/test_e2e.py (8 tests)
- T07: Globale Suche erweitert (Dokumente, Nachweise, Referenzen, Marktbegleiter)
- T08: Alle Migrationen sauber, 68/68 Tests grün, Ruff-Fehler in neuem Code behoben

Bugfix: URL-Namespace-Fehler in Abgabe-Templates (ausschreibungen:nachbetrachtung:abgabe → ausschreibungen:abgabe)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 17:54:38 +02:00
bde10f3a69 feat(WP-0011): Marktbegleiter-Analyse — Katalog, Passagen, Auswertung
Implementiert UC-MB-01 bis UC-MB-03: Marktbegleiter-Katalog (Liste,
Detail, Anlegen/Bearbeiten), Ausschreibungspassagen mit Verlässlichkeitsscore
(1–10, Validator), Musterauswertung mit Aggregationen (Ausschreiber-Häufigkeit,
Ø-Score, Passagen-Anzahl). 4 Tests grün.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 16:20:55 +02:00
278cc1014c feat(partner,bibliothek): Subunternehmer-Katalog, Dienstleistertypen und Bibliothek (WP-0010)
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>
2026-05-11 15:27:53 +02:00
a1cc317b3b feat(nachbetrachtung): Abgabe-Checkliste, Dokumentation und Nachbetrachtung (WP-0009)
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>
2026-05-11 15:09:38 +02:00
6991b0989e Workplan Preise has been implemented 2026-05-11 12:23:20 +02:00
c2c4ae3cbe Dokumentenmanagement 2026-05-08 18:33:04 +02:00
70ece97587 Aufgaben und Bieterfragen 2026-05-08 17:43:23 +02:00
f202b71c75 We are building, workplan now registered with statehub 2026-05-08 17:03:11 +02:00
14b0bc6d01 Prototype implementation 2026-05-08 14:26:48 +02:00