Reference AGENTS.md in CLAUDE.md and record verification claims for the architecture overview and operations runbook. Signed-off-by: Tim Krampitz <Tim.Krampitz@live.com>
9.7 KiB
type, title, description, tags, openwiki, verified
| type | title | description | tags | openwiki | verified | |||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Runbook | Operations, Environment Setup & Testing Guidance | Operational guide for local development setup, .NET Aspire startup, EF Core PostgreSQL migrations, JWT configuration, and testing verification scenarios. |
|
|
|
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 the backend and client architecture, manages database migrations for entities in the domain model, verifies real-time event flows defined in the workflow guide, and references source entrypoints cataloged in 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:
dotnet run --project SlipItIn.AppHost/SlipItIn.AppHost.csproj
What happens during launch:
- Aspire launches a PostgreSQL container (
pgsql/postgresdb). - Aspire builds and starts
SlipItIn.Server. Program.csautomatically executes EF Core migrations (db.Database.Migrate()), creating database tables if they do not exist.DbSeeder.SeedAsync(db)populates initial users and phrases when the database is empty.- 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, appsettings.Development.json, and environment variables.
Key Configuration Keys (SlipItIn.Server)
| Key | Default Value | Description |
|---|---|---|
Jwt:Key |
(none in production; dev fallback: DevOnlyKey-NotForProduction-ChangeMe-0123456789abcdef) |
Secret signing key for JWT tokens (Must be >= 32 characters / >= 256 bits). In non-development environments, a missing or short key causes a startup exception. |
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 injected by the Aspire orchestrator. |
Production Configuration Security
In production deployment, override Jwt:Key using environment variables or user secrets (dotnet user-secrets):
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:
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:
dotnet ef database update --project SlipItIn.Server --startup-project SlipItIn.Server
4. Test Project Structure
The SlipItIn.Server.Tests project contains all server-side automated tests. It targets net10.0 and uses xUnit as the test framework, Moq for mocking dependencies, and EF Core InMemory (Microsoft.EntityFrameworkCore.InMemory) for isolated database contexts.
Test Infrastructure
TestDbHelper.cs — Static helper class that creates isolated test databases and seeds test data:
CreateFactory()— Returns anIDbContextFactory<SlipItInDbContext>backed by an EF Core InMemory database with a unique name per test, ensuring complete test isolation.SeedUser(db, username, email, isActive)— Inserts a minimalUserentity and returns it.SeedPhrases(db, count)— Inserts a set ofPhraseentities (with an auto-created creator user) for card-dealing tests.SeedGame(db, host, status)— Creates aGamewith a hostPlayerattached, returning both for test assertions.
Test Files
| File | Class Under Test | What It Covers |
|---|---|---|
GameServiceTests.cs |
GameService |
Business logic: game creation, joining, starting, player ready, card dealing, slip submission, challenge creation/resolution, game state queries with round time computation. |
GameHubTests.cs |
GameHub |
SignalR hub behavior: lobby creation/join, player ready, game start, slip submission, challenge submission/resolution, authorization enforcement. Uses Moq to mock IGameService, IHubCallerClients, IGroupManager, and ISingleClientProxy. InMemory DB is used only for the hub's own player-access validation. |
AuthControllerTests.cs |
AuthController |
Registration (token generation, input validation, case-insensitive duplicate detection), login (credential verification, missing-field handling), and the /auth/me claims endpoint. |
DbSeederTests.cs |
DbSeeder |
Seed idempotency: verifies SeedAsync creates users and phrases when the database is empty, but does nothing when data already exists, and is safe to call repeatedly. |
Running Tests
dotnet test SlipItIn.Server.Tests/SlipItIn.Server.Tests.csproj
For CI-matching behavior (Release configuration):
dotnet test SlipItIn.Server.Tests/SlipItIn.Server.Tests.csproj --configuration Release
5. 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
GameHubrejects unauthenticated WebSocket connections or missing token query parameters. - Verification: Connect to
/hubs/gamewithout?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 thatValidatePlayerAccessAsyncthrowsUnauthorizedAccessExceptionand returns an error response.
3. Client MVVM Decoupled Messaging Tests
- Test Objective: Confirm
GameStateServicetranslates SignalR events intoWeakReferenceMessengermessages without memory leak risk. - Verification: Trigger a
GameStateUpdatedevent onSignalRService. Confirm thatLobbyViewModelandGameBoardViewModelreceiveGameStateChangedMessageand 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:
- Disconnect network or stop
SignalRService. - Invoke
GameBoardViewModel.SubmitSlipAsync(card). ConfirmQueuedGameActionis written toPreferences. - Re-establish connection. Confirm
GameStateService.ResyncAsync()callsRequestGameStateAsync()and replays the queued action viaSendQueuedActionAsync().
- Disconnect network or stop
5. Dual-Layer Local Storage Verification
- Test Objective: Confirm sensitive tokens are isolated in
SecureStoragewhile non-sensitive state stays inPreferences. - Verification: Inspect local device storage after login. Verify
auth_tokenis stored via platformSecureStorageandgame_state/queued_actionsare saved inPreferences.
6. Concurrency & Race Condition Tests
- Test Objective: Confirm
IDbContextFactoryhandles simultaneous WebSocket calls without thread collision. - Verification: Simulate 5 parallel calls to
GameHub.ChallengeSlip()orSubmitSlip()across multiple clients. Verify that all calls complete cleanly withoutInvalidOperationExceptionfrom DbContext.
6. 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.Serveras both project and startup-project. - Test offline queue flushing before submitting client-side real-time changes.
- Always run migrations using
- CI Build Commands (from
.github/workflows/build.yml):- Server stack:
dotnet build SlipItIn.Shared/SlipItIn.Shared.csproj --no-restore --configuration Release(and similarly forServiceDefaults,Server,Server.Tests,AppHost). - MAUI client:
dotnet build SlipItIn/SlipItIn.csproj --no-restore --configuration Debug. - Server tests:
dotnet test SlipItIn.Server.Tests/SlipItIn.Server.Tests.csproj --no-restore --configuration Release.
- Server stack:
- Minimal Validation Command:
dotnet build SlipItIn.slnx dotnet test SlipItIn.Server.Tests