Integration Test Plan & Report -- Mitgliederverwaltung
Test Plan: Gitea Issue #123
Execution Date: 2026-04-09
Tester: Claude (Playwright interactive testing)
Environment: Nextcloud 28, localhost:8080, admin user
App Version: 0.0.3
Test Plan (from Issue #123)
This test plan covers black-box UI testing of all features against the requirements spec (docs/requirements.md). Testing uses Playwright MCP tools to interact with the UI as an admin user.
Phases
| Phase |
Area |
Status |
| 0 |
Build & Deployment |
PASS |
| 1 |
Navigation & App Shell |
PASS (partial) |
| 2 |
Member Management |
FAIL (blocked by #125) |
| 3 |
Family Management |
PASS |
| 4 |
Stufen Management |
PARTIAL |
| 5 |
Fee System |
PASS (with issues) |
| 6 |
Search & Filtering |
PARTIAL |
| 7 |
Reports & Exports |
PASS |
| 8 |
Lagertracking |
PASS (empty state) |
| 9 |
Injury Tracking |
PASS (empty state) |
| 10 |
Audit Log |
FAIL |
| 11 |
Settings & Permissions |
PASS (with issues) |
| 12 |
Soft Deletion & DSGVO |
NOT TESTED |
| 13 |
Milestones |
NOT TESTED |
| 14 |
Data Validation Edge Cases |
NOT TESTED (blocked by #125) |
Linked Issues
| Issue |
Title |
Priority |
Status |
| #125 |
Member detail form fields render blank |
high |
open |
| #126 |
Audit log not recording any events |
high |
open |
| #127 |
Fee table shows member IDs instead of names |
medium |
open |
| #128 |
No default Stufen seeded on install |
low |
open |
| #129 |
Missing Lagerhistorie and Verletzungsprotokoll reports |
low |
open |
| #130 |
TypeError: e.find is not a function |
low |
open |
| #131 |
@nextcloud/vue appName/appVersion not configured |
low |
open |
| #133 |
Inline member search does not filter |
medium |
open |
| #134 |
Stufe column shows raw stufeId instead of name |
medium |
open |
| #135 |
Add missing pages to sidebar navigation |
medium |
open |
| #136 |
UX: Various minor UI polish issues |
low |
open |
Executive Summary
The Mitgliederverwaltung app has a solid architecture with many features already implemented. However, there is a critical, pervasive bug affecting all NcTextField form fields: values from the Vue store are not rendered into the form inputs. This affects member detail view, new member creation, Stufe name display in settings, and likely other form-based features. Additionally, the inline member search does not filter results.
1. Member Management
1.1 Member List (#/)
| Test Case |
Status |
Notes |
| Page loads with member table |
PASS |
5 members displayed correctly |
| Columns: Name, Stufe, Status, Alter, Rolle |
PASS |
All visible |
| Filter: Alle |
PASS |
Shows all 5 members |
| Filter: Aktive |
PASS |
Hides inactive Thomas Schmidt, shows 4 |
| Filter: Inaktive |
PASS |
Shows only Thomas Schmidt |
| Filter: Unbezahlte Beitraege |
PASS |
Button renders (not tested with data) |
| Filter: Geburtstage diesen Monat |
PASS |
Button renders (not tested with data) |
| Sorting by Name |
PASS |
Default sort ascending, toggleable |
| Inline search |
FAIL |
Typing "Weber" does not filter the list. NcTextField @update:value event does not fire properly, so store.searchMembers() is never called |
| Click row navigates to detail |
PASS |
Routes to #/members/:id |
| Pagination |
PASS |
Implemented but not visible with only 5 members |
Bugs
- BUG-001 (Critical): Inline search field does not filter the member list. The
NcTextField uses :value.sync (Vue 2 syntax) which may not work in Vue 3, and the @update:value event is not triggered by user input.
- BUG-002 (Medium): Stufe column shows raw
stufeId value (or "---") instead of the Stufe name. See MemberList.vue:107: {{ member.stufeId || '---' }} should resolve to Stufe name.
UX Issues
- UX-001: Two search bars visible -- one global SearchBar in the header and one inline NcTextField in the member list header. Confusing which to use. Consider removing one or clarifying their purpose.
- UX-002: "Neues Mitglied" button text truncates to "Neues ..." at certain viewport widths.
1.2 Member Detail (#/members/:id)
| Test Case |
Status |
Notes |
| Header shows member name |
PASS |
"Max Mustermann" displayed correctly |
| Info banner (Alter, Mitgliedsdauer, Status) |
PASS |
"13 Jahre", "6 Jahre, 3 Monate", green "Aktiv" badge |
| Tab navigation (7 tabs) |
PASS |
Persoenlich, Familie, Beitrag, Lager, Verletzungen, Dateien, Verlauf |
| Persoenlich tab -- form fields display |
FAIL |
All text fields are empty despite store having correct data |
| Edit mode toggle |
PASS |
"Bearbeiten" enables fields, shows "Speichern"/"Abbrechen" |
| Edit mode -- sub-entity buttons appear |
PASS |
"Adresse hinzufuegen", "Telefonnummer hinzufuegen", "E-Mail hinzufuegen" |
| Zurueck button |
PASS |
Navigates back to member list |
| Familie tab |
NOT IMPL |
Placeholder: "Wird in einem spaeteren Milestone implementiert." |
| Beitrag tab |
NOT IMPL |
Placeholder |
| Lager tab |
NOT IMPL |
Placeholder |
| Verletzungen tab |
NOT IMPL |
Placeholder |
| Dateien tab |
PASS |
FileExplorer works, shows folder path, offers "Ordner erstellen" |
| Verlauf tab |
NOT IMPL |
Placeholder |
Bugs
- BUG-003 (Critical): All form fields in MemberForm.vue display empty values in both view and edit mode. The
NcTextField :value prop does not render the bound data. The Vue store (members.currentMember) has correct data ({vorname: "Max", nachname: "Mustermann", ...}) but inputs show empty. Root cause: likely NcTextField expects :modelValue instead of :value in the Nextcloud Vue 8.x library used with Vue 3.
- BUG-004 (Critical): Saving a new member fails with 400 "Missing required fields: vorname, nachname, geburtsdatum, eintritt" because the
NcTextField @update:value events don't fire, so formData stays at initial empty values even though the user typed into the fields.
1.3 New Member (#/members/new)
| Test Case |
Status |
Notes |
| Form renders in edit mode |
PASS |
All fields enabled |
| Status field disabled for new members |
PASS |
Correct behavior |
| Rolle dropdown works |
PASS |
Shows "Mitglied", "Erziehungsberechtigter" |
| Save new member |
FAIL |
400 error due to BUG-004 |
UX Issues
- UX-003: "Erziehungsberechtigter" text breaks across lines in the NcSelect dropdown ("Erziehungsbe" / "rechtigter"). Dropdown needs
min-width or white-space: nowrap.
2. Family Management
2.1 Family List (#/families)
| Test Case |
Status |
Notes |
| Page loads |
PASS |
Shows "Keine Familien" empty state |
| Empty state with CTA |
PASS |
"Erste Familie anlegen" button shown |
| Search field |
PASS |
"Familien suchen..." placeholder |
| "Neue Familie" button |
PASS |
Visible but text may truncate |
2.2 Family Detail (#/families/new)
| Test Case |
Status |
Notes |
| Form loads |
PASS |
Familienname, Bankverbindung fields |
| Bankverbindung section |
PASS |
Kontoinhaber, IBAN (with example format), BIC, Kreditinstitut |
| Form buttons |
PASS |
Speichern, Abbrechen |
UX Issues
- UX-004: "Neue..." button text truncation on family list page.
3. Fee System (#/fees)
3.1 Fee Overview
| Test Case |
Status |
Notes |
| Page loads with fee records |
PASS |
3 records at 60.00 EUR each |
| Summary banner |
PASS |
Gesamt erwartet, Bezahlt, Ausstehend |
| Year selector |
PASS |
Dropdown with 2026, 2025 |
| "Beitraege berechnen" button |
PASS |
Visible and clickable |
| Mark fee as paid |
PASS |
Updates to "Ja", sets Zahlungsdatum, updates summary |
| "Betrag aendern" button |
PASS |
Visible (not tested action) |
| "Notiz" button |
PASS |
Visible (not tested action) |
| Erziehungsberechtigter excluded |
PASS |
Sabine Mustermann not in fee list |
| Inactive member excluded |
PASS |
Thomas Schmidt not in fee list |
Bugs
- BUG-005 (Medium): Members display as "Mitglied #1", "Mitglied #3", "Mitglied #5" instead of actual names (e.g., "Max Mustermann"). The member name resolution is broken.
4. Lager (Camp) Management (#/lager)
| Test Case |
Status |
Notes |
| Page loads |
PASS |
Shows table header and "Keine Lager gefunden" |
| Filter dropdowns |
PASS |
"Alle Jahre", "Alle Stufen" |
| "Neues Lager" button |
PASS |
Visible |
| Table columns |
PASS |
Name, Startdatum, Enddatum, Ort, Teilnehmer, Aktionen |
UX Issues
- UX-005: Empty state lacks an icon/illustration (unlike other empty states that use NcEmptyContent).
5. Injury Tracking (#/injuries)
| Test Case |
Status |
Notes |
| Page loads |
PASS |
"Verletzungsprotokoll" with table |
| Date range filters |
PASS |
Two date pickers |
| "Neue Verletzung" button |
PASS |
Visible |
| Table columns |
PASS |
Datum, Mitglied, Lager/Aktivitaet, Beschreibung, Beteiligte, Aktionen |
UX Issues
- UX-006: Injuries page is not accessible from the sidebar navigation. It requires direct URL or is only reachable from the member detail tab. Consider adding it to the sidebar.
6. Reports (#/reports)
| Test Case |
Status |
Notes |
| Report cards grid |
PASS |
8 report types in 2x4 grid |
| Report types |
PASS |
Mitgliederliste, Beitragsliste, Stufenliste, Allergieliste, Geburtstagsliste, Kontaktliste, Bankverbindungen, Familienliste |
| "Sensibel" badge on Bankverbindungen |
PASS |
Nice security awareness feature |
| Click report shows filter |
PASS |
Status filter dropdown appears |
| Preview (Vorschau) |
PASS |
Shows member table with correct data |
| Preview data formatting |
PASS |
German date format (DD.MM.YYYY) |
| Download buttons |
PASS |
PDF, CSV, Verschluesselt options shown |
UX Issues
- UX-007: "Bankverbindungen" text truncated on the card ("Bankverbindung...").
7. Import Wizard (#/import)
| Test Case |
Status |
Notes |
| Page loads with step indicator |
PASS |
5 steps: Hochladen, Zuordnung, Vorschau, Dry-Run, Ergebnis |
| File upload field |
PASS |
"Choose file" button with file input |
| Separator/encoding options |
PASS |
Trennzeichen (Komma), Kodierung (UTF-8) |
UX Issues
- UX-008: "Choose file" button shows English text (browser default). Consider using a custom styled button with German label "Datei auswaehlen".
- UX-009: Import page not accessible from sidebar navigation. Only accessible via direct URL.
8. Query Builder (#/queries)
| Test Case |
Status |
Notes |
| Page loads |
PASS |
"Abfrage-Builder" with saved queries panel |
| AND/OR toggle |
PASS |
UND/ODER buttons |
| Add condition |
PASS |
Creates row with field/operator/value |
| Default condition |
PASS |
"Vorname ist gleich Wert..." |
| Action buttons |
PASS |
Abfrage ausfuehren, Speichern, Zuruecksetzen |
| Saved queries panel |
PASS |
"Noch keine gespeicherten Abfragen" |
| Add group |
PASS |
Button present (not tested) |
UX Issues
- UX-010: Query builder page not accessible from sidebar navigation.
9. Audit Log (#/audit-log)
| Test Case |
Status |
Notes |
| Page loads |
PASS |
Filter panel with 5 filter fields |
| Filters: Entitaet, Benutzer, Entitaet-ID, Von, Bis |
PASS |
All rendered correctly |
| "Filter zuruecksetzen" button |
PASS |
Visible |
| Empty state |
PASS |
"Keine Eintraege" with helpful message |
Bugs
- BUG-006 (Medium): No audit entries logged despite performing state-changing operations (marking fee as paid). Audit logging may not be connected to fee operations, or there's a backend issue.
10. Settings (#/settings)
10.1 Stufen verwalten
| Test Case |
Status |
Notes |
| Stufe list renders |
PASS |
3 Stufen with age ranges and colors |
| Age range fields |
PASS |
6-12, 12-17, 18-99 |
| Color pickers |
PASS |
Yellow, Green, Red |
| Reorder arrows |
PASS |
Up/down arrows visible |
| "Neue Stufe" button |
PASS |
Visible |
| Member count per Stufe |
PASS |
Shows 0 for all (no members assigned) |
Bugs
- BUG-007 (Medium): Stufe name fields appear empty (same NcTextField binding issue as BUG-003). Names were configured but don't display.
10.2 Beitragsregeln
| Test Case |
Status |
Notes |
| Fee rule form |
PASS |
Gueltig ab Jahr, Grundbeitrag fields |
| Preview calculation |
PASS |
Shows 1. Kind 60 EUR, 2. Kind 45 EUR, Gesamt 105 EUR |
| Existing rules table |
PASS |
Shows 2026 rule (60.00 EUR) |
| "Regel speichern" button |
PASS |
Visible |
10.3 Berechtigungen verwalten
| Test Case |
Status |
Notes |
| User list |
PASS |
Shows admin user |
| User filter |
PASS |
"Benutzer filtern..." search field |
| Access level dropdown |
PASS |
"Kein Zugriff" shown for admin |
| "Bankdaten sichtbar" checkbox |
PASS |
Visible, unchecked |
UX Issues
- UX-011: Admin user shows "Kein Zugriff" (No Access) as default permission. This is confusing since the admin clearly has access. Consider auto-assigning admin role or showing a different default.
11. Navigation & Global UX
| Item |
Status |
Route |
| Mitglieder |
PASS |
#/ |
| Familien |
PASS |
#/families |
| Beitraege |
PASS |
#/fees |
| Lager |
PASS |
#/lager |
| Berichte |
PASS |
#/reports |
| Audit-Log |
PASS |
#/audit-log |
| Einstellungen |
PASS |
#/settings |
- Verletzungen (
#/injuries)
- Import (
#/import)
- Abfragen (
#/queries)
11.2 Global Search (SearchBar component)
The global SearchBar in the header is a separate, API-powered search with a dropdown results panel. It supports keyboard navigation, minimum 2-character input, and navigates to member detail on selection. This is distinct from the broken inline search in MemberList.
11.3 Console Errors
| Error |
Severity |
Description |
@nextcloud/vue: appName not set |
Low |
Configuration warning -- set appName in webpack config |
@nextcloud/vue: appVersion not set |
Low |
Configuration warning -- set appVersion in webpack config |
TypeError: e.find is not a function |
Medium |
Occurs on initial page load, likely in a store/component setup function trying to call .find() on a non-array value |
12. Not Implemented (Placeholder Tabs)
The following features show "Wird in einem spaeteren Milestone implementiert":
- Member detail: Familie tab (linking member to family from detail view)
- Member detail: Beitrag tab (showing fee history per member)
- Member detail: Lager tab (showing camp participation per member)
- Member detail: Verletzungen tab (showing injuries per member)
- Member detail: Verlauf tab (showing change history per member)
13. Summary of Findings
Critical Bugs (Must Fix)
| ID |
Description |
Impact |
| BUG-003 |
NcTextField :value prop does not display data |
All form views show empty fields |
| BUG-004 |
NcTextField @update:value does not emit on input |
Cannot save new members or edit existing ones |
Root Cause Analysis: Both BUG-003 and BUG-004 stem from the same issue. The app uses NcTextField with :value and @update:value, but the Nextcloud Vue 8.x library for Vue 3 likely expects :modelValue and @update:modelValue. This is the migration pattern from Vue 2 to Vue 3. The fix would be to update all NcTextField usages:
Similarly, in MemberList.vue, the :value.sync modifier is Vue 2 syntax that doesn't work in Vue 3.
Medium Bugs
| ID |
Description |
| BUG-001 |
Inline member search does not filter the list |
| BUG-002 |
Stufe column shows raw ID instead of name |
| BUG-005 |
Fee overview shows "Mitglied #N" instead of member names |
| BUG-006 |
Audit log shows no entries despite state changes |
| BUG-007 |
Stufe names not displayed in settings |
UX Improvements
| ID |
Description |
Priority |
| UX-001 |
Remove duplicate search bar or clarify purpose |
Medium |
| UX-002 |
Fix "Neues Mitglied" button text truncation |
Low |
| UX-003 |
Fix "Erziehungsberechtigter" text wrapping in dropdown |
Low |
| UX-004 |
Fix "Neue..." button text truncation on family list |
Low |
| UX-005 |
Add empty state icon to Lager list |
Low |
| UX-006 |
Add Injuries to sidebar navigation |
Medium |
| UX-007 |
Fix "Bankverbindungen" text truncation on report card |
Low |
| UX-008 |
Localize "Choose file" button to German |
Low |
| UX-009 |
Add Import to sidebar navigation |
Medium |
| UX-010 |
Add Query Builder to sidebar navigation |
Medium |
| UX-011 |
Clarify admin permission default in settings |
Medium |
Working Features (Verified)
- Member list with filter chips (Alle, Aktive, Inaktive, etc.)
- Member list sorting by all columns
- Member detail header with derived fields (age, membership duration)
- Member detail tab navigation
- Member detail Files tab (FileExplorer with Nextcloud Files integration)
- Family list with empty state and creation form
- Fee overview with summary, year selection, and payment tracking
- Lager list with filters
- Injury tracking list with date range filters
- Reports with 8 types, preview, and PDF/CSV/encrypted download
- Import wizard with 5-step process
- Query builder with AND/OR logic, conditions, groups, and saved queries
- Audit log with comprehensive filters
- Settings with Stufe management, fee rules, and permission management
- Global search (SearchBar) with API-powered dropdown results
- Sidebar navigation for main sections
14. Remaining Test Plan (Not Yet Executed)
The following phases from the test plan (Issue #123) were not tested in this session, either because they were blocked by #125 or require more complex setup:
Phase 12: Soft Deletion & DSGVO (Req 4.5, 4.6)
Phase 13: Milestones (Req 2.8)
Phase 14: Data Validation Edge Cases (Req 4.4)
Blocked by #125 -- cannot test form validation when forms don't accept input.
Deeper Testing (after #125 is fixed)