KoogleApp/docs/IMPLEMENTATION_PLAN.md

24 KiB

Koogle App - Analyse & Vorschlag für Bereiche und Pages

Zweck der Anwendung (abgeleitet aus Datenmodell)

Koogle ist eine Vereinsverwaltung für Kegelvereine mit Schwerpunkt auf:

Kernfunktionen

  1. Vereinsverwaltung: Multi-Mandanten-System, jeder Verein = eigener Scope
  2. Mitglieder & Gäste: Verwaltung von Personen mit Status (Member/Guest)
  3. Spieltagsorganisation: Planung und Durchführung von Kegeltagen (Days)
    • Status-Workflow: New → Started → Closed (oder Postponed)
    • Zuordnung von Teilnehmern pro Spieltag
  4. Spielverwaltung: Mehrere Games pro Day möglich
    • JSON-basierte Spielstände (GameData)
    • Teilnehmerzuordnung pro Game
  5. Kostenmanagement:
    • Vordefinierte Kosten/Strafen (Expenses) pro Verein
    • Automatische Trigger (z.B. Pudel, Pumpe, Aus, Kranz, etc.)
    • Variable/Fixe Preise, Inverse Kosten (alle außer einem zahlen)
    • One-Click Kosten für schnelle Erfassung
  6. Abrechnung:
    • Pro Person, pro Tag, pro Spiel
    • Berechnungsmethoden: None, Average, Maximum (für fehlende Personen)
    • Status: Open/Done für PersonExpenses
  7. Benutzer & Berechtigungen:
    • ASP.NET Identity mit Custom UserProfile
    • Rollen pro Verein: Viewer, Editor, Admin
    • SuperAdmin für vereinsübergreifende Verwaltung
    • Multi-Club Zugehörigkeit möglich

gerenelle Implementierungshinweise

  • im ersten Schritt wird die Anwendung in Deutscher Sprache implementiert. Alle Klassen, Methoden, Interfaces und sonstigen Artikefakte werden dennoch in englischer Sprache benannt. Auch die XMLDOC Kommentare werden in Englischer Sprache formuliert.
  • Der Anwender wird vom Programm in lockerem Ton und in der Du-Form angesprochen

Bestehende Implementierung

Vollständig implementiert

  • Authentication/Authorization Framework
  • Login mit Vereinsauswahl
  • Fluxor State Management (AuthState)
  • Rollenbasierte Berechtigungen
  • MudBlazor UI Framework
  • Dual DbContext (Domain + Identity)
  • Clean Architecture Struktur
  • Seeders (SuperAdmin, Roles)

Teilweise implementiert

  • ⚠️ DayService (vorhanden, aber auskommentiert)
  • ⚠️ Navigation (Skelett vorhanden, kaum Menüpunkte)

Nicht implementiert

  • UI für Clubs, Days, Games, Persons, Expenses
  • Services für Person, Game, Expense
  • DTOs für die meisten Domain Entities
  • Fluxor States für Domain-Daten
  • Reporting/Export-Funktionalität

Vorgeschlagene Bereiche & Pages

1. DASHBOARD-BEREICH (Startseite)

Route: / oder /dashboard

Zweck: Übersicht über aktuelle Aktivitäten im ausgewählten Verein

Pages:

  • Dashboard.razor:
    • Nächste geplante Spieltage
    • Aktuelle offene Kosten
    • Quick-Actions (neuer Spieltag, neue Person)
    • Statistiken (Anzahl Mitglieder, Gäste, offene Abrechnungen)

2. SPIELTAG-BEREICH (Day Management)

Route: /days

Pages:

  • DayList.razor (/days):

    • Tabelle: PostDate, Status, Teilnehmeranzahl
    • Filter: Jahr, Monat, Status
    • Actions: Neu, Bearbeiten, Löschen, Schließen
  • DayDetail.razor (/days/{id}):

    • Spieltag-Info (Datum, Status)
    • Teilnehmerliste mit Anwesenheit
    • Games des Tages
    • PersonExpenses des Tages (Übersicht)
    • Actions: Teilnehmer hinzufügen, Spiel hinzufügen, Status ändern
  • DayCreate.razor (/days/new):

    • Formular: Datum, Vorauswahl Teilnehmer aus Mitgliedern
  • DayEdit.razor (/days/{id}/edit):

    • Datum ändern, Teilnehmer hinzufügen/entfernen

3. SPIEL-BEREICH (Game Management)

Route: /days/{dayId}/games

Pages:

  • GameList.razor (/days/{dayId}/games):

    • Liste der Spiele eines Spieltags
    • Actions: Neues Spiel, Bearbeiten, Löschen
  • GameDetail.razor (/days/{dayId}/games/{gameId}):

    • GameData anzeigen/bearbeiten (JSON-Editor oder strukturierte Eingabe)
    • Teilnehmer des Spiels
    • Kosten des Spiels (PersonExpenses mit GameId)
    • Trigger-Events erfassen (z.B. "Pudel" → Expense zuweisen)
  • GameCreate.razor (/days/{dayId}/games/new):

    • Teilnehmer auswählen (aus DayPersons)
    • Optionale GameData-Initialisierung

4. KOSTEN-BEREICH (Expense Management)

Route: /expenses

Pages:

  • ExpenseList.razor (/expenses):

    • Vordefinierte Expenses des Vereins
    • Spalten: Name, Preis, Typ, IsOneClick, IsInverse, IsVariable
    • Actions: Neu, Bearbeiten, Löschen
  • ExpenseCreate.razor (/expenses/new):

    • Formular für neue Expense-Vorlage
    • Trigger-Zuordnung optional
  • PersonExpenseList.razor (/expenses/assigned):

    • Alle zugewiesenen Kosten (PersonExpenses)
    • Filter: Person, Tag, Status (Open/Done), Datum
    • Bulk-Actions: Als bezahlt markieren, Löschen
  • ExpenseTriggerConfig.razor (/expenses/triggers):

    • Trigger-Typen anzeigen
    • Zuordnung Trigger → Expense

5. PERSONEN-BEREICH (Person Management)

Route: /people

Pages:

  • PersonList.razor (/people):

    • Tabelle: Name, Status (Member/Guest), Actions
    • Filter: Status
    • Actions: Neu, Bearbeiten, Löschen
  • PersonCreate.razor (/people/new):

    • Name, Status
  • PersonDetail.razor (/people/{id}):

    • Personen-Info
    • Teilnahme-Historie (DayPersons)
    • Kosten-Historie (PersonExpenses)
    • Statistiken (Gesamtkosten, Anzahl Teilnahmen)

6. AUSWERTUNGEN-BEREICH (Reports/Evaluations)

Route: /reports

Pages:

  • ReportOverview.razor (/reports):

    • Auswahl: Pro Person, Pro Tag, Pro Spiel
  • PersonReport.razor (/reports/person/{id}):

    • Alle Kosten einer Person
    • Summen pro Tag, pro Spiel
    • Zeitraum-Filter
  • DayReport.razor (/reports/day/{id}):

    • Alle Kosten eines Spieltags
    • Aufschlüsselung pro Person
    • Export-Option (PDF, CSV)
  • PeriodReport.razor (/reports/period):

    • Zeitraum wählen (von-bis)
    • Aggregierte Statistiken
    • Top-Spieler, teuerste Tage, etc.

7. STAMMDATEN-BEREICH (Master Data - Vereins-spezifisch)

Route: /masterdata

Pages:

  • ClubSettings.razor (/masterdata/club):

    • Vereins-Name
    • ExpenseCalculation-Methode
    • Weitere Einstellungen
  • ExpenseTemplates.razor (/masterdata/expenses):

    • Siehe Expense-Bereich (evtl. Duplikat)
  • TriggerConfig.razor (/masterdata/triggers):

    • Siehe ExpenseTriggerConfig

8. ADMIN-BEREICH (SuperAdmin - Vereinsübergreifend)

Route: /admin

Pages:

  • ClubList.razor (/admin/clubs):

    • Alle Vereine (SuperAdmin only)
    • Actions: Neu, Bearbeiten, Löschen
  • ClubCreate.razor (/admin/clubs/new):

    • Name, ExpenseCalculation
  • UserManagement.razor (/admin/users):

    • Alle UserProfiles
    • Vereinszuordnung (UserProfileClub)
    • Rollen-Zuordnung pro Verein
  • SystemSettings.razor (/admin/system):

    • Globale Einstellungen

9. PROFIL-BEREICH (User Profile)

Route: /profile

Pages:

  • UserProfile.razor (/profile):
    • DisplayName, Locale, TimeZone ändern
    • Passwort ändern
    • Standard-Verein festlegen (UserProfileClub.IsDefault)
    • Vereins-Mitgliedschaften anzeigen

Vorgeschlagene Navigation-Struktur

NavMenu.razor:
├── 🏠 Dashboard (/)
├── 📅 Spieltage (/days)
├── 👥 Personen (/people)
├── 💰 Kosten
│   ├── Vorlagen (/expenses)
│   ├── Zugewiesen (/expenses/assigned)
│   └── Trigger (/expenses/triggers)
├── 📊 Auswertungen (/reports)
│   ├── Pro Person
│   ├── Pro Tag
│   └── Zeitraum
├── ⚙️ Stammdaten (IsClubEditor+)
│   ├── Verein (/masterdata/club)
│   └── Kosten-Vorlagen
├── 🔧 Admin (IsSuperAdmin)
│   ├── Vereine (/admin/clubs)
│   ├── Benutzer (/admin/users)
│   └── System (/admin/system)
└── 👤 Profil (/profile)

Prioritäts-Vorschlag (Phasen) - basierend auf User-Feedback

Phase 1: MVP - Basis-Verwaltung (DIESE PLANUNG)

Scope: User/Account-Mgmt, Club, Personen (Teilnehmer), Tage, Strafen

  1. User/Account-Verwaltung

    • User-Registrierung (self-service oder Admin)
    • Passwort zurücksetzen
    • User-zu-Club Zuordnung (UserProfileClub)
    • Rollen pro Club zuweisen (UserProfileClubRoleAssignment)
    • User-Profil (DisplayName, Locale, TimeZone)
  2. Club-Verwaltung (SuperAdmin)

    • Liste, Create, Edit, Delete
    • ExpenseCalculation-Methode
  3. Person-Verwaltung (Club-Teilnehmer: Members + Guests)

    • Liste, Create, Edit, Delete
    • Status (Member/Guest)
    • KEINE Login - reine Stammdaten für Kegelclub
  4. Day-Verwaltung

    • Liste, Create, Edit, Delete
    • Datum, Status (New, Started, Closed, Postponed)
    • Teilnehmer zuordnen (DayPerson)
  5. PersonExpense - Strafen manuell erfassen

    • Pro Teilnehmer pro Tag Strafen hinzufügen
    • Expense-Vorlagen (Name, Preis)
    • Status: Open/Done
  6. Dashboard

    • Übersicht: Nächste Tage, offene Kosten
    • Quick-Actions
  7. Einfache Auswertung

    • Pro Tag: Wer schuldet was
    • Pro Person: Summe offener Kosten

Phase 2: Detaillierte Spielverwaltung (SEPARATE PLANUNG SPÄTER)

NICHT in dieser Planung:

  • Wurf-für-Wurf Eingabe
  • Undo-Funktion
  • Plugin-System für verschiedene Kegelspiele
  • GameData strukturiert (JSON für jetzt)
  • Automatische Trigger (Pudel, Pumpe, etc.)
  • Expense-Trigger-Engine

Phase 3: Advanced Features (SPÄTER)

  • Export (PDF, CSV)
  • Benutzer-Rollen verwalten
  • Erweiterte Reports


IMPLEMENTIERUNGSPLAN - Phase 1 MVP

Umsetzungsreihenfolge - Übersicht

Phase Bereich Beschreibung Dateien
A1 Foundation Repository Interfaces 5 Interface-Dateien
A2 Foundation Repository Implementations 5 Repository-Dateien
A3 Foundation DTOs 5 DTO-Dateien
A4 Foundation Service Interfaces 5 Service-Interface-Dateien
A5 Foundation Service Implementations 5 Service-Dateien
A6 Foundation AutoMapper Profiles 5 Mapping-Dateien
A7 Foundation DI Registration 2 DI-Dateien ändern
B1 User/Account UserService erweitern 1 Service, 1 Interface, 1 DTO
B2 User/Account Register Page 1 Razor
B3 User/Account Password Reset Pages 2 Razor
B4 User/Account Profile Page 1 Razor
B5 User/Account Admin Users Page 1 Razor
C1 Clubs ClubState Fluxor 4 State-Dateien
C2 Clubs Club Pages - ERSTES TESTBARES MVP 1 Razor
D1 Personen PersonState Fluxor 4 State-Dateien
D2 Personen Person Pages 1 Razor
D3 Expenses ExpenseState Fluxor 4 State-Dateien
D4 Expenses Expense Pages 1 Razor
E1 Days DayState Fluxor 4 State-Dateien
E2 Days Days List Page 1 Razor
E3 Days Day Details Page 1 Razor
E4 Days PersonExpense Management Components in DayDetails
F1 Dashboard Dashboard Page 1 Razor
F2 Dashboard Evaluation Components 2 Shared Components
F3 Navigation NavMenu finalisieren 1 Razor ändern
G1 Erweiterte Reg. MembershipStatus + UserProfileClub 2 Dateien + Migration
G2 Erweiterte Reg. ClubInvitation Entity 1 Entity + Migration
G3 Erweiterte Reg. IEmailService (Stub) 2 Dateien
G4 Erweiterte Reg. Services erweitern 2 Services
G5 Erweiterte Reg. Dashboard Pending-Widget 1 Component
G6 Erweiterte Reg. Admin Users Page erweitern 1 Razor
G7 Erweiterte Reg. Club-Beitritt UI 1 Razor
G8 Erweiterte Reg. Einladungslink-Handling 2 Dateien

Legende: ☐ = Offen | ☑ = In Arbeit | ✓ = Fertig

Geschätzte Dateien insgesamt: ~90 Dateien


Detaillierte Phasen

Phase A1: Repository Interfaces erstellen

Dateien:

  1. src/Koogle.Domain/Interfaces/IClubRepository.cs
  2. src/Koogle.Domain/Interfaces/IPersonRepository.cs
  3. src/Koogle.Domain/Interfaces/IExpenseRepository.cs
  4. src/Koogle.Domain/Interfaces/IDayRepository.cs (erweitern)
  5. src/Koogle.Domain/Interfaces/IPersonExpenseRepository.cs

Methoden pro Interface: GetAllAsync/GetByClubIdAsync, GetByIdAsync, AddAsync, UpdateAsync, DeleteAsync


Phase A2: Repository Implementations erstellen

Dateien:

  1. src/Koogle.Infrastructure/Repositories/ClubRepository.cs
  2. src/Koogle.Infrastructure/Repositories/PersonRepository.cs
  3. src/Koogle.Infrastructure/Repositories/ExpenseRepository.cs
  4. src/Koogle.Infrastructure/Repositories/DayRepository.cs
  5. src/Koogle.Infrastructure/Repositories/PersonExpenseRepository.cs

Pattern: IDbContextFactory, ClubId-Filter, Include Navigation Properties


Phase A3: DTOs erstellen

Dateien:

  1. src/Koogle.Application/DTOs/ClubDto.cs (ClubDto, CreateClubDto, UpdateClubDto)
  2. src/Koogle.Application/DTOs/PersonDto.cs (PersonDto, CreatePersonDto, UpdatePersonDto)
  3. src/Koogle.Application/DTOs/ExpenseDto.cs (ExpenseDto, CreateExpenseDto, UpdateExpenseDto)
  4. src/Koogle.Application/DTOs/DayDto.cs erweitern (DayDto, CreateDayDto, UpdateDayDto, DayParticipantDto)
  5. src/Koogle.Application/DTOs/PersonExpenseDto.cs (PersonExpenseDto, CreatePersonExpenseDto, DayEvaluationDto, PersonDayEvaluationDto)

Phase A4: Service Interfaces erstellen

Dateien:

  1. src/Koogle.Application/Interfaces/IClubService.cs
  2. src/Koogle.Application/Interfaces/IPersonService.cs
  3. src/Koogle.Application/Interfaces/IExpenseService.cs
  4. src/Koogle.Application/Interfaces/IDayService.cs (erweitern)
  5. src/Koogle.Application/Interfaces/IPersonExpenseService.cs

Methoden: GetAllAsync, GetByIdAsync, CreateAsync, UpdateAsync, DeleteAsync + spezifische Methoden


Phase A5: Service Implementations erstellen

Dateien:

  1. src/Koogle.Application/Services/ClubService.cs
  2. src/Koogle.Application/Services/PersonService.cs
  3. src/Koogle.Application/Services/ExpenseService.cs
  4. src/Koogle.Application/Services/DayService.cs (erweitern)
  5. src/Koogle.Application/Services/PersonExpenseService.cs

Dependencies: Repository, ICurrentClubContext, ICurrentUserService, IMapper Business Logic: ClubId-Injection, Audit-Felder, Validierung (mittels FluentValidation)


Phase A6: AutoMapper Profiles erstellen

Dateien:

  1. src/Koogle.Application/Mapping/ClubMappingProfile.cs
  2. src/Koogle.Application/Mapping/PersonMappingProfile.cs
  3. src/Koogle.Application/Mapping/ExpenseMappingProfile.cs
  4. src/Koogle.Application/Mapping/DayMappingProfile.cs
  5. src/Koogle.Application/Mapping/PersonExpenseMappingProfile.cs

Pattern: CreateMap<Entity, Dto>() bidirektional


Phase A7: DI Registration

Dateien ändern:

  1. src/Koogle.Infrastructure/DependencyInjection.cs (5 Repositories registrieren)
  2. src/Koogle.Application/DependencyInjection.cs (5 Services registrieren)

Phase B1: UserService erweitern

Dateien:

  1. src/Koogle.Application/Interfaces/IUserService.cs erweitern
  2. src/Koogle.Application/Services/UserService.cs erweitern
  3. src/Koogle.Application/DTOs/UserDto.cs erweitern (RegisterUserDto, ResetPasswordDto, UpdateUserProfileDto)

Neue Methoden:

  • RegisterUserAsync
  • RequestPasswordResetAsync
  • ResetPasswordAsync
  • UpdateProfileAsync
  • AssignUserToClubAsync, RemoveUserFromClubAsync
  • AssignClubRoleAsync, RemoveClubRoleAsync

Phase B2: Register Page

Dateien:

  1. src/Koogle.Web/Components/Pages/Account/Register.razor

Features: Email, Password, DisplayName, Optional ClubName für initiale Zuordnung


Phase B3: Password Reset Pages

Dateien:

  1. src/Koogle.Web/Components/Pages/Account/ForgotPassword.razor
  2. src/Koogle.Web/Components/Pages/Account/ResetPassword.razor

Flow: Email eingeben → Token per Email → Passwort zurücksetzen


Phase B4: Profile Page

Dateien:

  1. src/Koogle.Web/Components/Pages/Account/Profile.razor

Features: DisplayName, Locale, TimeZone, Club-Memberships anzeigen, Standard-Club setzen


Phase B5: Admin Users Page

Dateien:

  1. src/Koogle.Web/Components/Pages/Admin/Users.razor

Features: User-Liste, Club-Zuordnungen, Rollen pro Club


Phase C1: ClubState (Fluxor)

Dateien:

  1. src/Koogle.Web/Store/ClubState/ClubState.cs
  2. src/Koogle.Web/Store/ClubState/ClubActions.cs
  3. src/Koogle.Web/Store/ClubState/ClubReducers.cs
  4. src/Koogle.Web/Store/ClubState/ClubEffects.cs

Actions: Load, Create, Update, Delete


Phase C2: Club Pages

Dateien:

  1. src/Koogle.Web/Components/Pages/Admin/Clubs.razor

Features: MudTable, CRUD-Dialogs, SuperAdmin only


Phase D1: PersonState (Fluxor)

Dateien:

  1. src/Koogle.Web/Store/PersonState/PersonState.cs
  2. src/Koogle.Web/Store/PersonState/PersonActions.cs
  3. src/Koogle.Web/Store/PersonState/PersonReducers.cs
  4. src/Koogle.Web/Store/PersonState/PersonEffects.cs

Phase D2: Person Pages

Dateien:

  1. src/Koogle.Web/Components/Pages/Persons/Persons.razor

Features: MudTable mit Filter (Member/Guest), CRUD


Phase D3: ExpenseState (Fluxor)

Dateien:

  1. src/Koogle.Web/Store/ExpenseState/ExpenseState.cs
  2. src/Koogle.Web/Store/ExpenseState/ExpenseActions.cs
  3. src/Koogle.Web/Store/ExpenseState/ExpenseReducers.cs
  4. src/Koogle.Web/Store/ExpenseState/ExpenseEffects.cs

Phase D4: Expense Pages

Dateien:

  1. src/Koogle.Web/Components/Pages/Expenses/Expenses.razor

Features: MudTable mit Expense-Vorlagen, CRUD


Phase E1: DayState (Fluxor)

Dateien:

  1. src/Koogle.Web/Store/DayState/DayState.cs
  2. src/Koogle.Web/Store/DayState/DayActions.cs
  3. src/Koogle.Web/Store/DayState/DayReducers.cs
  4. src/Koogle.Web/Store/DayState/DayEffects.cs

State: Days, SelectedDay, SelectedDayExpenses, AvailablePersons


Phase E2: Days List Page

Dateien:

  1. src/Koogle.Web/Components/Pages/Days/Days.razor

Features: MudTable mit Jahr-Filter, Create Day


Phase E3: Day Details Page

Dateien:

  1. src/Koogle.Web/Components/Pages/Days/DayDetails.razor

Features:

  • Day-Header (Datum, Status)
  • Status-Workflow Buttons (New→Started→Closed)
  • Teilnehmer-Sektion (Add/Remove)
  • PersonExpense-Sektion

Phase E4: PersonExpense Management

Components in DayDetails:

  • PersonExpense-Tabelle
  • Add Expense Dialog (Person auswählen, Expense auswählen, Preis editierbar wenn IsVariable)
  • Delete PersonExpense (nur in New/Started)
  • IsInverse Logic: 1 Person auswählen → alle anderen bekommen Expense

Phase F1: Dashboard Page

Dateien:

  1. src/Koogle.Web/Components/Pages/Dashboard.razor

Features: Summary Cards, Recent Days, Top Penalty Recipients


Phase F2: Evaluation Components

Dateien:

  1. src/Koogle.Web/Components/Shared/DayEvaluationComponent.razor
  2. src/Koogle.Web/Components/Shared/PersonEvaluationComponent.razor

Phase F3: Navigation finalisieren

Dateien ändern:

  1. src/Koogle.Web/Components/Layout/NavMenu.razor

Features: Dashboard, Spieltage, Stammdaten, Admin, Profil


Phase G1: MembershipStatus + UserProfileClub erweitern

Dateien:

  1. src/Koogle.Domain/Enums/MembershipStatus.cs (neu)

    • Pending, Approved, Rejected
  2. src/Koogle.Domain/Entities/UserProfileClub.cs (erweitern)

    • MembershipStatus Status (default: Pending)
    • string? RejectionReason
    • DateTime? ApprovedAt, Guid? ApprovedById
    • DateTime? RejectedAt, Guid? RejectedById
  3. Migration erstellen


Phase G2: ClubInvitation Entity

Dateien:

  1. src/Koogle.Domain/Entities/ClubInvitation.cs (neu)

    • Guid Id, Guid ClubId
    • string Token (unique, für URL)
    • DateTime ExpiresAt, DateTime CreatedAt, Guid CreatedById
    • int? MaxUses (null = unbegrenzt), int UsedCount
  2. src/Koogle.Infrastructure/Data/AppDbContext.cs - DbSet hinzufügen

  3. Migration erstellen


Phase G3: IEmailService (Stub)

Dateien:

  1. src/Koogle.Application/Interfaces/IEmailService.cs (neu)

    • SendMembershipRequestNotificationAsync
    • SendMembershipApprovedAsync
    • SendMembershipRejectedAsync
  2. src/Koogle.Infrastructure/Services/StubEmailService.cs (neu)

    • Logging statt echtem Versand
    • TODO-Kommentare für SMTP
  3. DI Registration


Phase G4: Services erweitern (Membership-Logik)

UserService erweitern:

  • RequestClubMembershipAsync(userProfileId, clubId)
  • RequestClubMembershipByNameAsync(userProfileId, clubName)
  • RequestClubMembershipByInviteAsync(userProfileId, inviteToken)
  • ApproveMembershipAsync(userProfileId, clubId, approvedById)
  • RejectMembershipAsync(userProfileId, clubId, rejectedById, reason)
  • GetPendingMembershipsAsync(clubId)

ClubService erweitern:

  • CreateInvitationAsync(clubId, createdById, expiresAt, maxUses)
  • GetInvitationByTokenAsync(token)
  • ValidateInvitationAsync(token)

Phase G5: Dashboard Pending-Widget

Dateien:

  1. src/Koogle.Web/Components/Shared/PendingMembershipsWidget.razor (neu)

    • Anzahl ausstehender Anträge für Club-Admins
    • Link zur Admin Users Page
  2. Dashboard.razor erweitern - Widget für Admins einbinden


Phase G6: Admin Users Page erweitern

Dateien:

  1. src/Koogle.Web/Components/Pages/Admin/Users.razor (ändern)
    • Tab/Filter für "Ausstehende Anträge"
    • Approve/Reject Buttons
    • Reject-Dialog mit Begründungsfeld

Phase G7: Club-Beitritt UI

Dateien:

  1. src/Koogle.Web/Components/Pages/Account/JoinClub.razor (neu)

    • Eingabefeld für Club-Name
    • Suche/Validierung
    • Beitrittsantrag senden
    • Erfolgsmeldung "Antrag gestellt"
  2. Dashboard.razor erweitern

    • "Keinem Club zugeordnet" Meldung mit Link zu JoinClub

Dateien:

  1. src/Koogle.Web/Components/Pages/Club/JoinByInvite.razor (neu)

    • Route: /club/join/{token}
    • Token validieren
    • Wenn eingeloggt: direkt Beitritt (Pending)
    • Wenn nicht eingeloggt: Redirect zu Register mit Token
  2. src/Koogle.Web/Controllers/AuthController.cs (erweitern)

    • InviteToken als optionalen Parameter bei Register

Zentrale Anforderungen (User-Feedback)

Business Rules

  1. PersonExpense.Price: Bei IsVariable=true editierbar, aber vorbelegt aus Expense
  2. Day Status-Workflow: Strikt New→Started→Closed, keine Sprünge
  3. User-Registrierung: Self-Service (öffentlich)
  4. Passwort-Reset: Email-basiert mit Token
  5. Day-Create: Alle Members vorbelegt, Gäste manuell
  6. PersonExpense löschen: Nur in Status New/Started
  7. Expense.IsInverse: Automatisch - 1 Person auswählen, alle anderen bekommen Expense
  8. Dashboard Zeitraum: Aktuelles Jahr

Code-Patterns & Konventionen

Repository Pattern

  • Interface in Domain/Interfaces
  • Implementation in Infrastructure/Repositories
  • Standard-Methoden: GetAllAsync, GetByIdAsync, AddAsync, UpdateAsync, DeleteAsync
  • ClubId-Filter via ICurrentClubContext
  • IDbContextFactory für Scoping

Service Pattern

  • Interface in Application/Interfaces
  • Implementation in Application/Services
  • Dependencies: Repository, ICurrentClubContext, ICurrentUserService, IMapper
  • ClubService: IsSuperAdmin Check
  • Audit-Felder auto-setzen (CreatedById, CreatedAt, ModifiedById, ModifiedAt)

Fluxor Pattern (Redux)

  • State: Record mit Collections + IsLoading + Error
  • Actions: Record per Operation (Load, LoadSuccess, LoadFailure, Create, Update, Delete)
  • Reducers: Pure functions, State transformieren
  • Effects: Async Operations, Service-Calls, Dispatcher

UI Pattern (Blazor + MudBlazor)

  • @inherits FluxorComponent
  • @attribute [Authorize(Policy = "...")]
  • MudTable für Listen
  • MudDialog für Create/Edit
  • MudForm mit Validation

Referenzdateien für Patterns

Service-Pattern:

  • src/Koogle.Application/Services/UserService.cs

Fluxor-Pattern:

  • src/Koogle.Web/Store/AuthState/AuthState.cs
  • src/Koogle.Web/Store/AuthState/AuthActions.cs
  • src/Koogle.Web/Store/AuthState/AuthReducers.cs
  • src/Koogle.Web/Store/AuthState/AuthEffects.cs

AutoMapper:

  • src/Koogle.Application/Mapping/UserProfile.cs

DI:

  • src/Koogle.Infrastructure/DependencyInjection.cs
  • src/Koogle.Application/DependencyInjection.cs

Domain:

  • src/Koogle.Domain/Entities/BaseEntity.cs

Berechtigungen pro Feature

  • Club-Verwaltung: SuperAdmin only
  • Person/Expense/Day CRUD: ClubEditor+
  • Dashboard/Auswertungen: ClubViewer+

Policy: @attribute [Authorize(Policy = "ClubViewer|ClubEditor|ClubAdmin")]


Zusammenfassung

23 feine Phasen~75 DateienMVP Phase 1 komplett

Bereit für Implementierung Phase A1