generated from coulomb/repo-seed
5.8 KiB
5.8 KiB
id, title, status, phase, created, depends_on
| id | title | status | phase | created | depends_on |
|---|---|---|---|---|---|
| WP-0007 | Dokumentenmanagement | done | 7-of-12 | 2026-05-08 | WP-0006 |
WP-0007 — Dokumentenmanagement
Upload, Kategorisierung, Versionierung, Statusworkflow und Standarddokument-Zuordnung für alle Dokumente. Referenz: UC-DO-01 bis UC-DO-05.
id: WP-0007-T01
title: Dokument-Upload und Kategorisierung (UC-DO-01)
status: done
`dokumente/views.py` — dokument_upload:
`DokumentForm(ModelForm)`:
Felder: datei (FileInput), kategorie (Select), version (Text, default='1.0'),
quelle (Text, blank), verantwortlicher (Select), pruefer (Select, blank), los (Select, blank).
`clean_datei()` prüft Dateiendung (.pdf, .docx, .xlsx, .zip, .png, .jpg, .jpeg) und
Dateigröße ≤ settings.MAX_UPLOAD_SIZE. Fehler: ValidationError mit klarer Meldung.
Nach erfolgreichem Upload:
- `dateiname` wird aus `datei.name` befüllt (`os.path.basename(form.instance.datei.name)`)
- Redirect zur Dokumentenliste der Ausschreibung
Multi-Upload: Zeige Dropzone (`<input type="file" multiple>`) mit Alpine.js-Preview der
gewählten Dateien (Dateinamen-Liste). Für jede Datei eigenes Formular-Submit
(vereinfacht: ein File at a time in v1).
id: WP-0007-T02
title: Dokumentenliste und Dokumentdetail
status: done
`dokumente/views.py` — dokumente_liste:
Zeigt alle Dokumente einer Ausschreibung, gruppiert nach Kategorie.
Filter: Status, Kategorie, Verantwortlicher.
Template `dokumente/liste.html`:
- Akkordeon nach Kategorie (Alpine.js)
- Tabelle: Dateiname (Download-Link), Version, Status-Badge, Verantwortlicher, Prüfer, Datum
- Rote Markierung für `finale_abgabeversion=True`
`dokument_detail`:
- Alle Felder via render_field
- Download-Button für Datei
- Versionshistorie (alle Dokumente gleicher Kategorie + Name, geordnet nach Version)
- Freigaben-Liste via GenericRelation
- CustomAttribute-Panel
id: WP-0007-T03
title: Neue Dokumentversion hochladen (UC-DO-02)
status: done
`dokument_neue_version (POST)`:
```python
def dokument_neue_version(request, ausschreibung_id, pk):
altes_dokument = get_object_or_404(Dokument, pk=pk, ausschreibung_id=ausschreibung_id)
form = DokumentVersionForm(request.POST, request.FILES)
if form.is_valid():
neues_dok = form.save(commit=False)
neues_dok.ausschreibung = altes_dokument.ausschreibung
neues_dok.los = altes_dokument.los
neues_dok.kategorie = altes_dokument.kategorie
neues_dok.verantwortlicher = altes_dokument.verantwortlicher
neues_dok.save()
altes_dokument.status = 'ersetzt'
altes_dokument.save(update_fields=['status'])
return redirect('dokumente:detail', ausschreibung_id=ausschreibung_id, pk=neues_dok.pk)
return render(request, 'dokumente/neue_version.html', {'form': form, 'dokument': altes_dokument})
DokumentVersionForm: Nur datei + version (vorausgefüllt mit inkrementierter Versionsnummer).
Logik naechste_version(alte_version_str): "1.0" → "2.0", "2.3" → "3.0" (Major-Inkrement für neue Versionen).
```task
id: WP-0007-T04
title: Dokumentstatus-Workflow und finale Abgabeversion (UC-DO-03, UC-DO-04)
status: done
**Status-Workflow** — HTMX-Widget analog zum Aufgaben-Status.
Statusübergänge: hochgeladen → zu_pruefen → in_bearbeitung → geprueft → freigegeben → final_abgegeben.
`dokument_status (POST)`:
Bei Übergang auf 'final_abgegeben': Setze automatisch `finale_abgabeversion=True`.
Bei Übergang auf 'final_abgegeben': Sperre weitere Status-Änderungen
(Widget rendert dann nur readonly Status-Badge ohne Dropdown).
**Finale Abgabeversion kennzeichnen** (UC-DO-04):
Zusätzlicher Button "Als finale Abgabeversion kennzeichnen" (außerhalb des normalen Workflows):
`dokument_finale_version (POST)`:
```python
def dokument_finale_version(request, ausschreibung_id, pk):
dok = get_object_or_404(Dokument, pk=pk)
dok.finale_abgabeversion = True
dok.status = 'final_abgegeben'
dok.save(update_fields=['finale_abgabeversion', 'status'])
return render(request, 'dokumente/partials/finaler_status_badge.html', {'dokument': dok})
Nach Kennzeichnung erscheint grüner "Final" Badge; weitere Uploads zu dieser Version gesperrt.
```task
id: WP-0007-T05
title: Standarddokument aus Bibliothek zuordnen (UC-DO-05)
status: done
`dokument_bibliothek_zuordnen`:
HTMX-Modal mit Suchfeld. Suche in `bibliothek.Nachweis` und Bibliothek-Dokumente.
Jeder Treffer zeigt: Titel, Kategorie, Version, Ablaufdatum, Freigabestatus.
Zuordnung erstellt **keinen** neuen Upload, sondern einen Dokument-Datensatz mit:
- `datei` = leer (null)
- `quelle` = "Bibliothek: <Nachweis-Titel>"
- `dateiname` = Nachweis-Titel
- Referenz auf Nachweis via FK (`bibliothek_nachweis` FK(Nachweis, null=True, SET_NULL) — ergänze Feld im Dokument-Modell + Migration)
Ablaufende/abgelaufene Nachweise: Zeige Warnung in orange/rot.
id: WP-0007-T06
title: Dokument-URL-Verkabelung und Tests
status: done
`dokumente/urls.py`:
```python
app_name = 'dokumente'
urlpatterns = [
path('', views.dokumente_liste, name='liste'),
path('hochladen/', views.dokument_upload, name='upload'),
path('<int:pk>/', views.dokument_detail, name='detail'),
path('<int:pk>/version/', views.dokument_neue_version, name='neue_version'),
path('<int:pk>/status/', views.dokument_status, name='status'),
path('<int:pk>/final/', views.dokument_finale_version, name='finale_version'),
path('<int:pk>/bibliothek/', views.dokument_bibliothek_zuordnen, name='bibliothek_zuordnen'),
]
Tests:
- Test: Upload mit gültigem PDF → Dokument in DB, Datei im Dateisystem
- Test: Upload mit ungültiger Dateierweiterung → ValidationError
- Test: Upload zu groß → ValidationError
- Test: Neue Version hochladen → altes Dokument hat status='ersetzt'
- Test: Finale Abgabeversion → finale_abgabeversion=True, Status gesperrt