mod planning

This commit is contained in:
beo3000 2025-12-26 10:47:53 +01:00
parent d2ee1c5193
commit fab82fcde8
1 changed files with 110 additions and 18 deletions

View File

@ -850,7 +850,8 @@ Spiele laufen im Speicher auf der DayDetails-Seite ohne Browser-Reload.
| Spiel-Ende | Auto-Ende + manuelle "Beenden" Option |
| Strafen-Schnellwahl | Nur im Details-Tab, nicht in Eingabe/Tafel |
| Multi-Game | Sequentiell - mehrere Spiele pro Tag, Liste sichtbar |
| Persistenz | JSON in `Game.GameData` nach Spielende speichern |
| Persistenz | **Nach jedem Wurf** in DB speichern (Game.GameData) |
| Multi-User | Spielfortschritt in anderen Sessions via **SignalR** sichtbar |
| Scheiss-Spiel Ende | Erster mit 0 Punkten **gewinnt**, andere bekommen Strafen nach Restpunkten |
| Strafen-Berechnung | Fixbetrag pro Restpunkt (z.B. 0.10€ × 30 Punkte = 3.00€) |
@ -862,22 +863,55 @@ Spiele laufen im Speicher auf der DayDetails-Seite ohne Browser-Reload.
| View-Wechsel | ViewMode-Enum + MudTabs (kein URL-Routing) |
| Spieltyp-System | IGameDefinition in Domain, Registry in Application |
| Pin-Komponenten | Port aus KoogleApp mit neuem Namespace |
| Persistenz | In-Memory während Spiel → DB (Game.GameData) bei Ende |
| Persistenz | **Nach jedem Wurf** → DB (Game.GameData JSON) |
| Recovery | Bei Page-Load: aktives Spiel aus DB laden |
| Multi-User Sync | **SignalR** für Echtzeit-Updates (Live-Tafel) |
## Existierende Entity
## Game Entity (erweitern)
```csharp
// Koogle.Domain/Entities/Game.cs - bereits vorhanden
// Koogle.Domain/Entities/Game.cs - erweitern
public class Game : BaseEntity
{
public string GameData { get; set; } = "{}"; // JSON für Spielergebnis
public string GameData { get; set; } = "{}"; // JSON für kompletten Spielzustand
public Guid DayId { get; set; }
public Day Day { get; set; }
public ICollection<GamePerson> GamePersons { get; set; }
public Guid ClubId { get; set; }
public Club Club { get; set; }
// NEU:
public string GameType { get; set; } = ""; // "Training", "Shit"
public GameStatus Status { get; set; } // Active, Completed, Aborted
public DateTime? StartedAt { get; set; }
public DateTime? CompletedAt { get; set; }
}
public enum GameStatus { Active, Completed, Aborted }
```
## GameData JSON Struktur (Beispiel Training)
```json
{
"gameType": "Training",
"throwPanelState": {
"throwsPerRound": 3,
"throwMode": "Reposition",
"totalThrowCounter": 42
},
"participants": {
"playerIds": ["guid1", "guid2"],
"currentPlayerIndex": 1
},
"gameModel": {
"playerStatistics": {
"guid1": { "throwCount": 21, "pinCount": 145, "circleCount": 2 },
"guid2": { "throwCount": 21, "pinCount": 138, "circleCount": 1 }
}
},
"undoStack": [ ... ]
}
// → GameType Property hinzufügen (string oder Enum)
```
## Architektur
@ -900,10 +934,11 @@ Web: Store/GameState/, Components/Game/
| ☐ | H6 | UI | Game Setup Dialog | 4 |
| ☐ | H7 | Integration | DayDetails Integration | 3 |
| ☐ | H8 | Features | Undo/Redo | 3 |
| ☐ | H9 | Features | Session Persistence | 2 |
| ☐ | H9 | Persistenz | DB Persistence & Recovery | 4 |
| ☐ | H9b | Sync | SignalR Live-Updates | 4 |
| ☐ | H10 | Testing | Game Tests | 3 |
**Geschätzte Dateien: ~42 neue/modifizierte**
**Geschätzte Dateien: ~48 neue/modifizierte**
---
@ -1166,16 +1201,66 @@ public record ShitGameModel
---
### **Phase H9: Session Persistence**
### **Phase H9: DB Persistence & Recovery**
**Dateien:**
1. `src/Koogle.Web/wwwroot/js/gameSession.js`
2. `src/Koogle.Web/Store/GameState/GameEffects.cs` (erweitern)
1. `src/Koogle.Application/Interfaces/IGamePersistenceService.cs`
2. `src/Koogle.Application/Services/GamePersistenceService.cs`
3. `src/Koogle.Web/Store/GameState/GameEffects.cs` (erweitern)
4. `src/Koogle.Application/DTOs/GameStateDto.cs` (JSON-Serialisierung)
**Mechanismus:**
- Bei State-Änderung: SessionStorage speichern
- Bei Page-Load: SessionStorage prüfen
- Wenn Session für aktuellen DayId existiert: Restore anbieten
**Methoden:**
- `SaveGameStateAsync(Guid gameId, GameState state)` - Nach jedem Wurf
- `LoadActiveGameAsync(Guid dayId)` - Bei Page-Load
- `GetCompletedGamesAsync(Guid dayId)` - Für Spiele-Liste
**Persistenz-Flow:**
```
1. Spiel starten → Game Entity mit Status=Active erstellen
2. Nach jedem Wurf:
- GameState → JSON serialisieren
- Game.GameData updaten (Debounced, max 1x/500ms)
3. Page Reload / Andere Session:
- LoadActiveGameAsync(dayId)
- Wenn Active Game existiert → GameState wiederherstellen
4. Spiel beenden:
- Status = Completed, CompletedAt = now
- Finales GameData speichern
```
---
### **Phase H9b: SignalR Live-Updates**
**Dateien:**
1. `src/Koogle.Web/Hubs/GameHub.cs`
2. `src/Koogle.Web/Hubs/IGameHubClient.cs`
3. `src/Koogle.Web/Store/GameState/GameEffects.cs` (erweitern für Broadcast)
4. `src/Koogle.Web/Program.cs` (AddSignalR, MapHub)
**SignalR Hub:**
```csharp
public class GameHub : Hub<IGameHubClient>
{
public async Task JoinGame(Guid gameId)
=> await Groups.AddToGroupAsync(Context.ConnectionId, gameId.ToString());
public async Task LeaveGame(Guid gameId)
=> await Groups.RemoveFromGroupAsync(Context.ConnectionId, gameId.ToString());
}
public interface IGameHubClient
{
Task GameStateUpdated(GameStateDto state);
Task GameEnded(GameResultDto result);
}
```
**Flow:**
1. Tafel-View öffnen → `JoinGame(gameId)`
2. Nach jedem Wurf: DB Save → `Clients.Group(gameId).GameStateUpdated(state)`
3. Andere Sessions empfangen Update → Reducer aktualisiert State
4. Tafel-View schließen → `LeaveGame(gameId)`
---
@ -1224,8 +1309,8 @@ public record ShitGameModel
## Migration
```bash
# GameType Property zu Game Entity hinzufügen
dotnet ef migrations add AddGameType --project src/Koogle.Infrastructure --startup-project src/Koogle.Web --context AppDbContext --output-dir Data/Migrations
# Game Entity erweitern: GameType, Status, StartedAt, CompletedAt
dotnet ef migrations add ExtendGameEntity --project src/Koogle.Infrastructure --startup-project src/Koogle.Web --context AppDbContext --output-dir Data/Migrations
dotnet ef database update -p src/Koogle.Infrastructure -s src/Koogle.Web --context AppDbContext
```
@ -1242,6 +1327,13 @@ dotnet ef database update -p src/Koogle.Infrastructure -s src/Koogle.Web --conte
## Zusammenfassung Phase 2
**10 Phasen (H1-H10)** → **~42 Dateien** → **Detaillierte Spielverwaltung**
**11 Phasen (H1-H10 + H9b)** → **~48 Dateien** → **Detaillierte Spielverwaltung**
**Kernfeatures:**
- Spiele mit Wurf-für-Wurf Eingabe
- DB-Persistenz nach jedem Wurf
- SignalR Live-Updates für Multi-User
- Recovery bei Page-Reload
- Undo/Redo für Wurf-Korrekturen
Bereit für Implementierung Phase H1