Files
SlipItIn/openwiki/operations/runbook.md
2026-08-08 12:50:15 +02:00

131 lines
6.6 KiB
Markdown

---
type: Runbook
title: Operations, Environment Setup & Testing Guidance
description: Operational guide for launching SlipItIn with .NET Aspire, running EF Core PostgreSQL migrations, configuring secrets, and executing client/server verification tests.
tags: [operations, runbook, spire, postgresql, migrations, testing, mvvm, offline-queue]
openwiki:
roles: [operations, testing]
change_kinds: [lifecycle, public-api]
source_paths: [SlipItIn.AppHost/AppHost.cs, SlipItIn.Server/Program.cs, SlipItIn/MauiProgram.cs]
symbols: [AppHost, Program, MauiProgram]
validation_commands: ["dotnet build SlipItIn.slnx"]
---
# Operations, Environment Setup & Testing Guidance
This runbook provides actionable instructions for local development setup, starting services via .NET Aspire, executing Entity Framework Core migrations, configuring environment keys, running client/server applications, and executing targeted test scenarios.
This guide [configures environment parameters for](/openwiki/architecture/overview.md) the backend and client architecture, [manages database migrations for entities in](/openwiki/domain/game-mechanics.md) the domain model, [verifies real-time event flows defined in](/openwiki/workflows/slip-and-challenge.md) the workflow guide, and [references source entrypoints cataloged in](/openwiki/source-map.md) the source map.
---
## 1. Local Development Environment Setup
### Prerequisites
* **.NET 10 SDK** (Installed and verified via `dotnet --version`).
* **Docker Desktop** or **Podman** (Required by .NET Aspire to run the PostgreSQL container).
* **Workloads**: .NET Aspire workload and .NET MAUI workload (`dotnet workload install aspire maui`).
### Starting the Distributed Application with Aspire
Run the Aspire orchestrator project:
```bash
dotnet run --project SlipItIn.AppHost/SlipItIn.AppHost.csproj
```
**What happens during launch:**
1. Aspire launches a PostgreSQL container (`pgsql`/`postgresdb`).
2. Aspire builds and starts `SlipItIn.Server`.
3. `Program.cs` automatically executes EF Core migrations (`db.Database.Migrate()`), creating database tables if they do not exist.
4. Aspire Dashboard opens in your web browser, displaying live metrics, OpenTelemetry traces, and structured logs for all services.
---
## 2. Configuration & Secrets Management
Configuration settings are loaded from `appsettings.json` and environment variables.
### Key Configuration Keys (`SlipItIn.Server`)
| Key | Default Value | Description |
|---|---|---|
| `Jwt:Key` | `YourSuperSecretKeyThatIsAtLeast32CharactersLong!` | Secret signing key for JWT tokens (Must be >= 256 bits). |
| `Jwt:Issuer` | `SlipItInServer` | Token issuer claim. |
| `Jwt:Audience` | `SlipItInClient` | Token audience claim. |
| `Jwt:ExpirationMinutes` | `1440` (24 hours) | JWT token lifespan. |
| `ConnectionStrings:postgresdb` | Configured via Aspire | PostgreSQL connection string. |
### Production Configuration Security
In production deployment, override `Jwt:Key` using environment variables or user secrets (`dotnet user-secrets`):
```bash
dotnet user-secrets set "Jwt:Key" "YOUR_HIGH_ENTROPY_PRODUCTION_SECRET_KEY_HERE" --project SlipItIn.Server
```
---
## 3. Entity Framework Core Migrations
When altering models in `SlipItIn.Shared/Models/` or `SlipItInDbContext.cs`:
### Adding a New Migration
Run the EF Core CLI from the repository root:
```bash
dotnet ef migrations add <MigrationName> --project SlipItIn.Server --startup-project SlipItIn.Server
```
### Applying Migrations Manually
While `Program.cs` applies migrations at startup (`db.Database.Migrate()`), migrations can also be manually applied via command line:
```bash
dotnet ef database update --project SlipItIn.Server --startup-project SlipItIn.Server
```
---
## 4. Testing Guidance & Verification Scenarios
When developing or extending SlipItIn features, verify the core architecture through these targeted test scenarios:
### 1. JWT Authentication & Claims Tests
* **Test Objective**: Verify `GameHub` rejects unauthenticated WebSocket connections or missing token query parameters.
* **Verification**: Connect to `/hubs/game` without `?access_token=...` or with an expired token. Confirm SignalR connection is terminated with 401 Unauthorized.
### 2. Player Access Authorization Tests
* **Test Objective**: Verify Player A cannot manipulate Player B's cards or state.
* **Verification**: Authenticate as User A and attempt to call `GameHub.SubmitSlip(gameId, playerBId, cardId)`. Verify that `ValidatePlayerAccessAsync` throws `UnauthorizedAccessException` and returns an error response.
### 3. Client MVVM Decoupled Messaging Tests
* **Test Objective**: Confirm `GameStateService` translates SignalR events into `WeakReferenceMessenger` messages without memory leak risk.
* **Verification**: Trigger a `GameStateUpdated` event on `SignalRService`. Confirm that `LobbyViewModel` and `GameBoardViewModel` receive `GameStateChangedMessage` and update their observable collections cleanly.
### 4. Offline Action Queueing & Resync Verification
* **Test Objective**: Verify actions taken while disconnected are stored locally and replayed upon reconnection.
* **Verification**:
1. Disconnect network or stop `SignalRService`.
2. Invoke `GameBoardViewModel.SubmitSlipAsync(card)`. Confirm `QueuedGameAction` is written to `Preferences`.
3. Re-establish connection. Confirm `GameStateService.ResyncAsync()` calls `RequestGameStateAsync()` and replays the queued action via `SendQueuedActionAsync()`.
### 5. Dual-Layer Local Storage Verification
* **Test Objective**: Confirm sensitive tokens are isolated in `SecureStorage` while non-sensitive state stays in `Preferences`.
* **Verification**: Inspect local device storage after login. Verify `auth_token` is stored via platform `SecureStorage` and `game_state` / `queued_actions` are saved in `Preferences`.
### 6. Concurrency & Race Condition Tests
* **Test Objective**: Confirm `IDbContextFactory` handles simultaneous WebSocket calls without thread collision.
* **Verification**: Simulate 5 parallel calls to `GameHub.ChallengeSlip()` or `SubmitSlip()` across multiple clients. Verify that all calls complete cleanly without `InvalidOperationException` from DbContext.
---
## 5. Guidance for Future Agents & Developers
- **When to Consult**: Refer to this runbook for local environment setup, Aspire startup commands, EF Core migration commands, and test verification procedures.
- **Invariants**:
- Always run migrations using `SlipItIn.Server` as both project and startup-project.
- Test offline queue flushing before submitting client-side real-time changes.
- **Minimal Validation Command**:
```bash
dotnet build SlipItIn.slnx
```