Update der Dokumentation
This commit is contained in:
@@ -1,15 +1,21 @@
|
||||
---
|
||||
type: Overview
|
||||
title: SlipItIn Code Wiki Quickstart
|
||||
description: Entrypoint for SlipItIn - a real-time multiplayer party game built with .NET 10, MAUI, ASP.NET Core SignalR, EF Core PostgreSQL, and .NET Aspire.
|
||||
tags: [quickstart, overview, slipitin, dotnet10, spire]
|
||||
description: Entrypoint for SlipItIn - a real-time multiplayer party game built with .NET 10, MAUI MVVM, ASP.NET Core SignalR, EF Core PostgreSQL, and .NET Aspire.
|
||||
tags: [quickstart, overview, slipitin, dotnet10, spire, maui, mvvm]
|
||||
openwiki:
|
||||
roles: [architecture, domain, workflow]
|
||||
change_kinds: [public-api, lifecycle]
|
||||
source_paths: [SlipItIn/MauiProgram.cs, SlipItIn.Server/Program.cs, SlipItIn.AppHost/AppHost.cs]
|
||||
symbols: [MauiProgram, SignalRService, GameStateService, GameHub, GameService]
|
||||
validation_commands: ["dotnet build SlipItIn.slnx"]
|
||||
---
|
||||
|
||||
# SlipItIn Code Wiki Quickstart
|
||||
|
||||
Welcome to the **SlipItIn** repository wiki. SlipItIn is a real-time multiplayer party game where players receive secret phrase cards and attempt to "slip" those phrases into everyday conversations or text chats without getting caught by other players.
|
||||
|
||||
The solution is built using **.NET 10**, leveraging **ASP.NET Core Web API & SignalR** for the backend engine, **Entity Framework Core (Npgsql / PostgreSQL)** for data persistence, **.NET MAUI** for the cross-platform client app, and **.NET Aspire** for distributed cloud-native orchestration and telemetry.
|
||||
The solution is built using **.NET 10**, leveraging **ASP.NET Core Web API & SignalR** for the backend engine, **Entity Framework Core (Npgsql / PostgreSQL)** for data persistence, **.NET MAUI (MVVM Pattern)** for the cross-platform client app, and **.NET Aspire** for distributed cloud-native orchestration and telemetry.
|
||||
|
||||
---
|
||||
|
||||
@@ -21,47 +27,62 @@ The repository is organized as a multi-project .NET solution (`SlipItIn.slnx`):
|
||||
SlipItIN/
|
||||
├── SlipItIn.AppHost/ # .NET Aspire AppHost orchestrator (pgsql + server + client)
|
||||
├── SlipItIn.Server/ # ASP.NET Core Web API + SignalR Hub + Game Engine
|
||||
├── SlipItIn.Shared/ # Shared Class Library (Models & DTOs)
|
||||
├── SlipItIn.Shared/ # Shared Class Library (Models, DTOs & Enums)
|
||||
├── SlipItIn.ServiceDefaults/ # Aspire OpenTelemetry, Health Checks & Service Discovery
|
||||
└── SlipItIn/ # .NET MAUI Client App (Android, iOS, MacCatalyst, Windows)
|
||||
└── SlipItIn/ # .NET MAUI Client App (MVVM: Views, ViewModels, Services, Messages)
|
||||
```
|
||||
|
||||
The system architecture [orchestrates services with](/openwiki/operations/runbook.md) .NET Aspire and [enforces security and privacy on](/openwiki/domain/game-mechanics.md) all domain entities. For a deep dive into the backend design, JWT security, and concurrency safety, see the [System Architecture & Security Overview](/openwiki/architecture/overview.md).
|
||||
The system architecture [orchestrates services with](/openwiki/operations/runbook.md) .NET Aspire and [enforces security and privacy on](/openwiki/domain/game-mechanics.md) all domain entities. For a deep dive into backend security, SignalR real-time client integration, MVVM architecture, and offline queueing, see the [System Architecture & Security Overview](/openwiki/architecture/overview.md).
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
MAUI[SlipItIn .NET MAUI Client] -->|REST / API| Server[SlipItIn.Server ASP.NET Core]
|
||||
MAUI -->|SignalR WebSockets| Hub[GameHub /hubs/game]
|
||||
Server -->|IDbContextFactory| DB[(PostgreSQL Database)]
|
||||
AppHost[.NET Aspire AppHost] -->|Orchestrates| Server
|
||||
subgraph MAUI_Client["SlipItIn .NET MAUI Client"]
|
||||
Views["Views (LoginPage, LobbyPage, GameBoardPage)"] --> ViewModels["ViewModels (LoginVM, LobbyVM, GameBoardVM)"]
|
||||
ViewModels --> GameState["GameStateService"]
|
||||
GameState --> SignalR["SignalRService"]
|
||||
GameState --> LocalStorage["LocalStorageService (SecureStorage & Preferences)"]
|
||||
ViewModels --> ApiService["ApiService (REST Auth)"]
|
||||
end
|
||||
|
||||
ApiService -->|REST /api/auth| AuthCtrl["AuthController"]
|
||||
SignalR -->|WebSockets /hubs/game| Hub["GameHub"]
|
||||
Hub --> Service["GameService"]
|
||||
AuthCtrl --> DB[("PostgreSQL Database")]
|
||||
Service -->|IDbContextFactory| DB
|
||||
AppHost[".NET Aspire AppHost"] -->|Orchestrates| Server["SlipItIn.Server"]
|
||||
AppHost -->|Provisions| DB
|
||||
Server -->|Uses Defaults| ServiceDefaults[SlipItIn.ServiceDefaults]
|
||||
```
|
||||
*System architecture diagram illustrating .NET MAUI MVVM client layer, backend REST/SignalR APIs, and .NET Aspire PostgreSQL orchestration.*
|
||||
|
||||
---
|
||||
|
||||
## 2. Core Game Loop & Mechanics
|
||||
|
||||
1. **Lobby Creation**: Host creates a game lobby with a 6-character code. Players join via code.
|
||||
2. **Card Dealing**: Upon game start, each player receives a private hand of 5 secret phrase cards (`PlayerHandDto`).
|
||||
3. **Phrase Slipping**: During normal conversation, a player speaks or types one of their phrases and clicks **Submit Slip**.
|
||||
4. **Slip Challenge**: Opponents suspecting a fake phrase can issue a **Slip Challenge**.
|
||||
- **Justified Accusation (Approved)**: Target phrase was an invalid slip.
|
||||
- **False Accusation (Rejected)**: Target phrase was legitimate. The accuser receives the card as a penalty (expanding their hand size beyond 5).
|
||||
1. **Authentication & Session**: Player registers or logs in via `LoginPage` / `RegisterPage`. `AuthSessionService` stores the JWT token in `SecureStorage`.
|
||||
2. **Lobby Creation**: Host creates a lobby on `LobbyPage`, generating a 6-character code. Players join using the code.
|
||||
3. **Card Dealing**: Upon game start, each player receives a private hand of 5 secret phrase cards (`PlayerHandDto`) via SignalR unicast.
|
||||
4. **Phrase Slipping**: During normal conversation, a player speaks or types one of their phrases and clicks **Submit Slip** on `GameBoardPage`. If offline, actions queue locally in `QueuedGameAction` and flush automatically upon reconnection.
|
||||
5. **Slip Challenge**: Opponents suspecting a fake phrase can issue a **Slip Challenge**.
|
||||
- **Justified Accusation (Approved)**: Target phrase was an invalid slip. Card remains with accused player.
|
||||
- **False Accusation (Rejected)**: Target phrase was legitimate. The accuser receives the phrase card as a penalty.
|
||||
|
||||
To learn how game events flow across SignalR in real time, inspect the [Slip & Challenge Workflows](/openwiki/workflows/slip-and-challenge.md).
|
||||
|
||||
---
|
||||
|
||||
## 3. Wiki Navigation Map
|
||||
## 3. Task Routing & Navigation Map
|
||||
|
||||
Explore specific documentation sections for technical details:
|
||||
The following task routing table directs future engineers and automated agents to relevant wiki documentation, source entry points, key symbols, and verification commands for common modification scenarios:
|
||||
|
||||
- **[System Architecture & Security Overview](/openwiki/architecture/overview.md)**: Explains .NET Aspire orchestration, JWT bearer authentication, claims validation, `IDbContextFactory` thread safety, and public vs. private data isolation.
|
||||
- **[Game Domain & State Models](/openwiki/domain/game-mechanics.md)**: Details domain entities (`User`, `Game`, `Player`, `Phrase`, `PlayerCard`, `GameRound`, `SlipChallenge`) and their state lifecycles.
|
||||
- **[Slip & Challenge Workflows](/openwiki/workflows/slip-and-challenge.md)**: Details step-by-step game loop execution, real-time SignalR notifications, and penalty rules.
|
||||
- **[Source Code Map](/openwiki/source-map.md)**: Directory and file navigation index mapping repository paths to technical domains.
|
||||
- **[Operations & Runbook](/openwiki/operations/runbook.md)**: Instructions for running the app with Aspire, executing PostgreSQL EF Core migrations, configuration keys, and testing strategies.
|
||||
| Intent / Change Area | Relevant Wiki Page | Source Entry Points | Key Symbols / Types | Focused Checks | Minimal Validation Command |
|
||||
|---|---|---|---|---|---|
|
||||
| **MAUI Client ViewModels & Pages** | [Architecture Overview](/openwiki/architecture/overview.md) | `SlipItIn/ViewModels/`, `SlipItIn/Views/` | `LobbyViewModel`, `GameBoardViewModel`, `LoginViewModel` | Inspect MVVM command handlers and `WeakReferenceMessenger` bindings | `dotnet build SlipItIn/SlipItIn.csproj` |
|
||||
| **Client SignalR & Messaging** | [Slip & Challenge Workflows](/openwiki/workflows/slip-and-challenge.md) | `SlipItIn/Services/SignalRService.cs`, `SlipItIn/Services/GameStateService.cs` | `ISignalRService`, `IGameStateService`, `WeakReferenceMessenger` | Verify auto-reconnect backoff and message dispatching | `dotnet build SlipItIn/SlipItIn.csproj` |
|
||||
| **Offline Action Queue & Resync** | [Slip & Challenge Workflows](/openwiki/workflows/slip-and-challenge.md) | `SlipItIn/Services/GameStateService.cs`, `SlipItIn/Models/QueuedGameAction.cs` | `QueuedGameAction`, `EnqueueActionAsync`, `FlushQueuedActionsAsync` | Verify offline queueing in `Preferences` and flush on reconnect | `dotnet build SlipItIn/SlipItIn.csproj` |
|
||||
| **Local Storage & Auth Session** | [Architecture Overview](/openwiki/architecture/overview.md) | `SlipItIn/Services/LocalStorageService.cs`, `SlipItIn/Services/AuthSessionService.cs` | `ILocalStorageService`, `IAuthSessionService`, `SecureStorage` | Confirm JWT stored in `SecureStorage` and state in `Preferences` | `dotnet build SlipItIn/SlipItIn.csproj` |
|
||||
| **Backend Game Engine & Hub** | [Architecture Overview](/openwiki/architecture/overview.md) | `SlipItIn.Server/Hubs/GameHub.cs`, `SlipItIn.Server/Services/GameService.cs` | `GameHub`, `GameService`, `IDbContextFactory` | Test JWT claim extraction and EF Core DbContext session isolation | `dotnet build SlipItIn.Server/SlipItIn.Server.csproj` |
|
||||
| **Domain Models & DTOs** | [Game Domain & State Models](/openwiki/domain/game-mechanics.md) | `SlipItIn.Shared/Models/`, `SlipItIn.Shared/DTOs/` | `GameStateDto`, `PlayerHandDto`, `SlipChallengeDto`, `QueuedGameAction` | Confirm card privacy isolation between public state and private hand | `dotnet build SlipItIn.Shared/SlipItIn.Shared.csproj` |
|
||||
| **Aspire & Infrastructure Setup** | [Operations & Runbook](/openwiki/operations/runbook.md) | `SlipItIn.AppHost/AppHost.cs`, `SlipItIn.ServiceDefaults/` | `AppHost`, `AddServiceDefaults`, `AddPostgres` | Validate Aspire service references and PostgreSQL container creation | `dotnet run --project SlipItIn.AppHost/SlipItIn.AppHost.csproj` |
|
||||
|
||||
---
|
||||
|
||||
@@ -72,6 +93,8 @@ When modifying this repository, strictly adhere to these core rules:
|
||||
1. **IDbContextFactory Thread Safety**: Never inject a scoped `SlipItInDbContext` into SignalR hubs or singleton services. Always use `IDbContextFactory<SlipItInDbContext>.CreateDbContext()` to prevent DbContext concurrency exceptions during concurrent WebSocket calls ([Architecture Overview](/openwiki/architecture/overview.md)).
|
||||
2. **Data Privacy Isolation**: Do not leak card text into public DTOs. Public game state must be broadcast using `GameStateDto` (card counts only), while private cards are dispatched strictly via `PlayerHandDto` to individual client connections ([Domain Mechanics](/openwiki/domain/game-mechanics.md)).
|
||||
3. **Server-Side Validation**: SignalR client calls represent intent ("I want to challenge X"). The server MUST re-verify JWT claims, player game membership, card ownership, and round status inside `GameHub.cs` and `GameService.cs` before mutating state ([Slip & Challenge Workflows](/openwiki/workflows/slip-and-challenge.md)).
|
||||
4. **Decoupled Client Messaging**: MAUI ViewModels MUST NOT consume `ISignalRService` events directly for UI updates. Always route events through `IGameStateService` via `WeakReferenceMessenger` messages (`GameStateChangedMessage`, `PlayerHandChangedMessage`, `ChallengeReceivedMessage`) to prevent memory leaks and dangling subscriptions ([Architecture Overview](/openwiki/architecture/overview.md)).
|
||||
5. **Dual-Layer Local Storage**: Always store sensitive credentials (JWT access tokens) in platform `SecureStorage`. Non-sensitive UI states, cached game data, and offline action queues MUST be persisted in `Preferences` ([Architecture Overview](/openwiki/architecture/overview.md)).
|
||||
|
||||
---
|
||||
|
||||
@@ -79,6 +102,4 @@ When modifying this repository, strictly adhere to these core rules:
|
||||
|
||||
The following features and components are specified in specification documents (`Agents/ProjectPlan.md` and `Agents/Architecture.md`) and backlogged for upcoming development iterations:
|
||||
|
||||
- **MAUI Client Services & ViewModels**: Implement `ApiService`, `SignalRService`, `GameStateService`, `LobbyViewModel`, and `GameBoardViewModel` under `SlipItIn/` using `CommunityToolkit.Mvvm` and `WeakReferenceMessenger`. (Anchor: `SlipItIn/`, pending client phase 3 completion).
|
||||
- **Offline Action Queue & Auto-Resync**: Implement exponential backoff reconnect logic (0s, 2s, 10s, 30s) and queued action execution upon app resume in MAUI client. (Anchor: `SlipItIn/Services/`, deferred until MAUI service layer setup).
|
||||
- **Timer Engine for Slip Rounds**: Background timer service on server enforcing round duration limits (30-60s) with automated round completion notifications. (Anchor: `SlipItIn.Server/Services/`, pending phase 2b refinement).
|
||||
|
||||
Reference in New Issue
Block a user